web-dev-qa-db-fra.com

AsyncTask onPostExecute n'est jamais appelée

Je ne suis pas sûr de ce que je fais mal mais onPostExecute n'est jamais appelé.

  • Création d'une classe de base appelée BaseActivity.Java
  • A partir de mon activité initiale, j'ai étendu ce cours.
  • Classe PostToOpenFeint placée dans BaseActivity
  • Je l'ai appelé depuis le fil de l'interface utilisateur de l'activité principale que je faisais: 

    new PostToOpenFeint.execute();
    

OnPreExecute (), doInBackground (..) est déclenché, mais pour une raison quelconque, onPostExecute n'est jamais appelé.

Merci d'avance!

Dave

 private class PostToOpenFeint extends AsyncTask<Void, Void, Void> {
  /*
   * (non-Javadoc)
   * 
   * @see Android.os.AsyncTask#doInBackground(Params[])
   */
  @Override
  protected Void doInBackground(Void... params) {
   // does all the work here
   return null;
  }


  /*
   * (non-Javadoc)
   * 
   * @see Android.os.AsyncTask#onPostExecute(Java.lang.Object)
   */
  @Override
  protected void onPostExecute(Void result) {
   // TODO Auto-generated method stub
   super.onPostExecute(result);
   Toast.makeText(MainScreen.this, "Done syncing", Toast.LENGTH_LONG).show();
  }

  /*
   * (non-Javadoc)
   * 
   * @see Android.os.AsyncTask#onPreExecute()
   */
  @Override
  protected void onPreExecute() {
   // TODO Auto-generated method stub
   super.onPreExecute();
   Toast.makeText(MainScreen.this, "About to sync all your scores", Toast.LENGTH_LONG).show();
  }

En regardant de plus près, c'est ce que j'ai pu observer. Par exemple si je passe cet appel: 

 new PostToOpenFeint.execute();

juste après onCreate of Activity, alors tout fonctionne bien. Si je place cet appel, dites à l'intérieur d'un écouteur à boutons.

settingsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
   new PostToOpenFeint.execute();
}
});

OnPostExecute () n'est jamais appelé, pas sûr de ce que je fais mal. La restriction que j'ai lue était d'appeler cela à partir du thread d'interface utilisateur et je l'appelle à partir du thread d'interface utilisateur.

39
ddavtian

J'ai eu un problème similaire tout à l'heure. J'étendais AsyncTask<Integer,Integer,Integer> et ma méthode onPostExecute ressemblait à ceci:

protected void onPostExecute(int result)

Cela me semblait correct, mais là encore je suis plus un gars de .NET qu'un gars de Java . Je l'ai changé en:

protected void onPostExecute(Integer result)

parce que, pour une raison quelconque, Java pense qu’il existe une différence entre int et Integer?

Je pense que votre problème est que vous déclarez le type de retour sous la forme void dans votre:

extends<Void,Void,Void>

Cela signifie pas de paramètres, pas de progrès et aucun résultat. Si vous voulez exécuter quelque chose quand c'est fait, je pense que vous devez lui donner une sorte de valeur comme et un entier ou un booléen.

Si vous changez votre étend à:

<Void,Void,Integer>

Maintenant, vous ne passez aucun paramètre, vous ne publiez aucun progrès, mais vous retournez une valeur. Changez votre méthode onPostExecute pour accepter une Integer:

protected void onPostExecute(Integer result)

Puis changez le retour dans votre méthode doInBackground en quelque chose comme:

return 1;

Ensuite, il devrait exécuter pour vous.

73
Tom E.

Il y a encore une chose à propos d'AsyncTasks sur laquelle je viens de passer la moitié de la journée:

La classe AsyncTask doit être chargée sur le thread d'interface utilisateur. C'est fait automatiquement à partir de JELLY_BEAN.

Dit la documentation. Sur le pain d'épice (et probablement avant), dans les bonnes circonstances, ceci entraîne que onPostExecute ne soit pas exécuté. La solution, cependant, est facile, juste un 

new MyAsyncTask();

tôt dans le thread d'interface utilisateur afin que la classe soit chargée avant que quoi que ce soit en arrière-plan ne puisse la charger par inadvertance.

J'avais utilisé une fonction statique dans ma sous-classe AsyncTask à partir d'un thread d'arrière-plan appelé, en fonction du temps, avant tout élément du thread utilisé dans cette sous-classe AsyncTask, et bingo, un Nice Heisenbug.

(Ours avec moi pour répondre à cette question ancienne, déjà répondu, mais je n'ai pas trouvé cette friandise d'information nulle part, et ceci est mon premier post)

12
Christian Mock

Notez que si vous annulez la tâche via cancel() , onPostExecute() ne sera pas appelé. C'est assez logique, mais oublier un appel à cette méthode m'avait laissé perplexe.

9
Paul Lammertsma

Mon problème était que d'une manière ou d'une autre je n'avais pas @ Override la méthode onPostExecute correctement. J'ai corrigé cela en cliquant avec le bouton droit de la souris-> source-> Remplacer\Implémenter la méthode.

Espère que ça aide quelqu'un

7
Oz Radiano

Peut-être que le code dans doInBackground () ne revient jamais?

2
Kevin Gaudin

Ajoutez simplement ceci au code de votre activité. C'est le problème de la tâche asynchrone ne s'initialisant pas correctement comme elle est supposée le faire.

          try {
                Class.forName("Android.os.AsyncTask");
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
1
Rajesh Narwal

Utilisez simplement les paramètres appropriés dans onPostExecute, utilisation public void onPostExecute (réponse booléenne) {} au lieu de public void onPostExecute (réponse booléenne) {} Cela a résolu mon problème.

0
vinaya

Il suffit de changer les paramètres dans onPostExecute

@Override
protected void onPostExecute(Void unused) {
...}

Maintenant, la méthode devrait être appelée. 

0
Michael Kronberger