2017-07-31 2 views
1

Je suis débutant dans AsyncTask, et j'ai eu un problème. J'ai AsyncTask, qui enregistre des informations dans DB en appelant la fonction d'une autre classe. Le problème est que la méthode onPostExecute appelle avant que ma fonction se termine; Voici mon code:Comment attendre jusqu'à ce que la méthode d'une autre classe dans asynctask se termine dans android

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(); 
    } 
} 

Je l'ai déjà essayé de mettre tous les appels en OnPreExecute, mais le résultat est toujours le même. Aussi, comme un avis, le premier bloc de code sql (cycle) est géré avec succès, pas comme gestionnaire de films et d'utilisateurs. Comment appeler launchRecyclerView après l'exécution complète d'AsyncTask?

+1

'Le problème est que la méthode onPostExecute appelle avant ma fonction finishes' probablement vous utilisez un autre fil de de' doInBackground' workThread –

+2

onPostExecute exécutera seulement après la fin de doInBackground. Si FilmHandler et Userhandler sont implémentés sur un thread séparé, cela peut provoquer le problème. Pour éviter cela, n'utilisez pas un autre thread pour enregistrer des données dans DB au lieu de compléter l'ensemble des données d'enregistrement dans le doInBackground lui-même. –

+0

Alors, comment pourrais-je lancer FilmHandler et UserHandler int dans le même fil? –

Répondre

0

Votre méthode doInBackgound() doit "attendre" vos cours FilmHandler, UserHandler pour terminer. Je pense que vos classes travaillent sur un thread d'arrière-plan. Lorsque vous les utilisez, votre code continue immédiatement à l'instruction return null - et termine le travail en arrière-plan, provoquant l'appel de onPostExecute().

Modifiez l'implémentation de votre classe pour qu'elle fonctionne sur le thread appelant et ne crée pas la leur.

+0

Existe-t-il un exemple d'implémentation de l'utilisation du thread appelant? –

+0

Ce serait très spécifique et bien au-delà de ce que je pourrais expliquer dans stackOverFlow. Je vous suggère de commencer par lire le code source des classes et de voir quelles techniques asynchrones utilisent (Thread, AsyncTask etc ...). – mrsegev

0

Pouvez-vous s'il vous plaît ajouter du contexte à doinbackground paramètre comme well.Might être getcontext retour contexte null/Application

0

onPostExecute exécutera seulement après la fin de doInBackground. Si FilmHandler et Userhandler sont implémentés sur un thread séparé, cela peut provoquer le problème. Donc, pour éviter cela, n'utilisez pas un autre thread pour enregistrer des données dans la base de données (ou). Effectuez un autre type d'opération à la place complétez l'intégralité des données d'enregistrement dans le doInBackground lui-même.

Sinon il y a une autre façon dont vous pouvez également archiver la fonctionnalité. Vous devez ajouter un rappel pour les fonctions filmHandler ou userHandler et vérifier la mise à jour en doinBackground et en fonction de ce que vous pouvez passer le résultat à 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 

} 

}

Dans un autre point comme indiqué par @ user3413619 peut être getContext() renvoie null donc, essayez de le rendre YourActivity.this

+0

J'ai oublié d'ajouter, que ce code est en Fragment, donc je ne peux pas utiliser Activity.this –

+0

Ensuite, vous devez ajouter getActivity() au lieu de getContext().essayez ceci avec vos anciens codes –

+0

J'ai changé comme vous l'avez dit mais le problème reste toujours –

0

make doInBackground méthode return type boolean et passez le résultat à postExecute boolean puis vérifiez si le résultat est vrai quelle méthode vous voulez appeler.

Merci