2017-07-31 8 views
1

私はAsyncTaskの初心者で問題があります。 AsyncTaskは、別のクラスの関数を呼び出してDBに情報を保存します。問題は、関数が終了する前にonPostExecuteメソッドが呼び出されていることです。ここに私のコードです:asynctaskの別のクラスのメソッドがアンドロイドで終了するまでの方法

class checkNewReviews2 extends AsyncTask<List<ReviewList.ReviewItem>, Void, Void>{ 


    @Override 
    protected Void doInBackground(List<ReviewList.ReviewItem>... reviewList) { 

     int size = reviewList[0].size(); 
     if(size>0) { 

      for (int i = 0; i < size; i++) { 
       ReviewList.ReviewItem r = reviewList[0].get(i); 
       ContentValues c = new ContentValues(); 
       c.put(LentaClass.LentaListEntry.FILM_ID, r.getFilm_id()); 
       c.put(LentaClass.LentaListEntry.USER_ID, r.getUser_id()); 
       c.put(LentaClass.LentaListEntry.REVIEW_TEXT, r.getReview_text()); 
       c.put(LentaClass.LentaListEntry.CREATED_AT, r.getCreated_at()); 
       c.put(LentaClass.LentaListEntry.REVIEW_TYPE, r.getReview_type()); 
       c.put(LentaClass.LentaListEntry.VIEWS, r.getViews()); 
       sqLiteDatabase.insert(LentaClass.LentaListEntry.TABLE_NAME, null, c); 

       c.clear(); 
      } 
      FilmHandler filmHandler = new FilmHandler(getContext()); 
      filmHandler.HandleFilms(reviewList[0]); 
      UserHandler userHandler = new UserHandler(getContext()); 
      userHandler.HandleUsers(reviewList[0]); 


     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

     initiateRecyclerView(); 
    } 
} 

私はすでにすべての呼び出しをonPreExecuteに入れようとしましたが、結果は変わりません。また、通知として、SQLコード(サイクル)の最初のブロックは、フィルムおよびユーザーハンドラとしてではなく、正常に処理されます。 AsyncTaskが完全に実行された後、InitateRecyclerViewをどのように呼び出すべきですか?

+1

は '問題はonPostExecute方法はおそらくあなたがdoInBackground' workThread –

+2

onPostExecuteだけdoInBackgroundの完了後に実行される他のスレッドの'から使用している私の関数finishes'の前に呼び出していることです。 FilmHandlerとUserhandlerが別々のスレッドに実装されている場合、問題が発生する可能性があります。これを避けるには、代わりに別のスレッドを使用してdoInBackground自体の保存データ全体を完了させます。 –

+0

したがって、私はFilmHandlerとUserHandlerを同じスレッドで実行できますか? –

答えて

0

お客様のdoInBackgound()メソッドは、FilmHandlerUserHandlerクラスが終了するまで「待機」する必要があります。

私の推測では、あなたのクラスはバックグラウンドスレッド上で動作しているので、コードを使用するとただちにreturn nullステートメントに進み、バックグラウンド作業を終了してonPostExecute()を呼び出します。

呼び出しのスレッドで動作するようにクラスの実装を変更し、独自のものを作成しないでください。

+0

呼び出しスレッドの使用方法を実装する方法の例はありますか? –

+0

これは非常に具体的で、stackOverFlowでexsplainできる範囲を超えています。まず、クラスのソースコードを読んで、使用している非同期技術(Thread、AsyncTaskなど)を見てみましょう。 – mrsegev

0

あなたはonPostExecuteだけdoInBackgroundの完了後に実行されます

0

ヌル/アプリケーション・コンテキストを返すのgetcontextことwell.Mightなどのパラメータをdoinbackgroundするコンテキストを追加してくださいすることができます。 FilmHandlerとUserhandlerが別々のスレッドで実装されている場合、問題が発生する可能性があります。これを避けるには、別のスレッドを使用してDB(または)のデータを保存しないでください。代わりに他の種類の操作を実行すると、doInBackground自体の保存データ全体が完了します。

これ以外の方法でも機能をアーカイブできます。述べたようにあなたはfilmHandlerまたはuserHandler機能のためのコールバックを追加し、doinBackgroundで更新を確認し、それに基づいて、あなたは別のポイントでPostExcecute()

class checkNewReviews2 extends AsyncTask<List<ReviewList.ReviewItem>, Void, Boolean>{ 


@Override 
protected Void doInBackground(List<ReviewList.ReviewItem>... reviewList) { 

    int size = reviewList[0].size(); 
    if(size>0) { 

     for (int i = 0; i < size; i++) { 
      ReviewList.ReviewItem r = reviewList[0].get(i); 
      ContentValues c = new ContentValues(); 
      c.put(LentaClass.LentaListEntry.FILM_ID, r.getFilm_id()); 
      c.put(LentaClass.LentaListEntry.USER_ID, r.getUser_id()); 
      c.put(LentaClass.LentaListEntry.REVIEW_TEXT, r.getReview_text()); 
      c.put(LentaClass.LentaListEntry.CREATED_AT, r.getCreated_at()); 
      c.put(LentaClass.LentaListEntry.REVIEW_TYPE, r.getReview_type()); 
      c.put(LentaClass.LentaListEntry.VIEWS, r.getViews()); 
      sqLiteDatabase.insert(LentaClass.LentaListEntry.TABLE_NAME, null, c); 

      c.clear(); 
     } 


     FilmHandler filmHandler = new FilmHandler(YourActivity.this); 
     boolean filmHandlerState = filmHandler.HandleFilms(reviewList[0]); 
     UserHandler userHandler = new UserHandler(YourActivity.this); 
     boolean userHandlerState = userHandler.HandleUsers(reviewList[0]); 



     if(filmHandlerState && userHandlerState) 
     { 
     return true; 
     } 
     else 
     { 
     return false; 
     } 
    } 
} 

@Override 
protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

     if(result) 
    { 
     initiateRecyclerView(); 
    } 
    else 
    { 
     // any one of the filmHandler or userHandler function has failed. so do your handling here 

} 

}

に結果を渡すことができますする必要があります@ user3413619である可能性がありますgetContext()はnullを返すので、それを作ってみましょうYourActivity.this

+0

私はこのコードが断片になっているので、Activity.this –

+0

を使用することを忘れてしまいました。次に、getContext()の代わりにgetActivity()を追加する必要があります。あなたの古いコードでこれを試してください –

+0

あなたが言ったように私は変更されましたが、問題はまだ残っています –

0

doInBackgroundメソッド戻り値の型booleanを渡して、結果をpostExecute booleanに渡して、呼び出したいメソッドを実行します。

おかげ

関連する問題