web-dev-qa-db-fra.com

Comment appeler la fonction d'activité parent de ASyncTask?

setAccountAuthenticatorResult peut être appelé à partir de l'activité, qui étend AccountAuthenticatorActivity. Mon activité va plus loin, mais lance ASyncTask et donc cette setAccountAuthenticatorResult devrait être appelée depuis ASyncTask (ou le résultat de ASyncTask devrait être renvoyé au thread principal).

Comment faire?

Quel est le problème dans le code ci-dessous?

AsyncTask<Uri, Void, Bundle> task = new RetrieveAccessTokenTask(this, consumer, provider, prefs).execute(uri);

public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Bundle> {
    private Context context;

    public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,
            OAuthProvider provider, SharedPreferences prefs) {
        this.context = context;
    }

    @Override
    protected void onPostExecute(Bundle result) {
        context.setAccountAuthenticatorResult(); // doesn't work

    }
19
LA_

Lorsque vous créez la AsyncTask, vous pouvez y ajouter un nouveau constructeur et lui transmettre une référence à l'activité:

AsyncTask myTask = new MyTask(this);

Et ensuite, à partir de la méthode onPostExecute () dans AsyncTask, vous pouvez appeler la méthode sur l'activité.

public class MyTask extends AsyncTask<String, String, String>
{
    public MyActivity activity;

    public MyTask(MyActivity a)
    {
        this.activity = a;
    }

    //  ......

    protected void onPostExecute(String result)
    {
        activity.myMethod();
    }
}
68
Ollie C

Utiliser l'interface

Suivez ces étapes:

1) Créer une interface

public interface AsyncTaskListener{

   public void updateResult(String result);

}

2) Utiliser listener dans votre AsyncTask

DownloadSongTask extends AsyncTask<String,Integer,String>{

   private AsyncTaskListener listener;

   public DownloadSongTask(Context context)
   {
       listener= (AsyncTaskListener)context;    // Typecast 
   }

   @Override
   public void doInbackGround(String... params)
   {
       // Download code
       int downloadPerc = // calculate that
       publish(downloadPerc);   
   }

   @Override
   public void onPostExecute(String result)
   {
       listener.updateResult(String result);  // Use it 
   }

}

3) Implémenter l'interface dans la méthode Activity and Override

  public class YourActivity extends AppcompatActivity implements AsyncTaskListener{

  // Activity code //
  new  DownloadSongTask(this).execute("Paradise.mp3");  // this is how you start Task

  public void yourMethod(String arg)
  {
    // Your method related Stuff
  }

  @Override 
  public void updateResult(String result){
        yourMethod(result);
  }

}

Advantege d'utiliser une interface?

Cela semble une approche longue au début, mais en utilisant cette approche 

Vous pouvez rendre votre AsyncTask indépendante de toute activité utilisant Interface. Si vous souhaitez utiliser la même tâche asynchrone avec différentes activités, alors L’approche d’interface est la meilleure car votre AsyncTask peut être utilisée avec n’importe quel. Activité sans même changer le code dans la tâche Async. C'est ainsi vous créez une AsyncTask faiblement couplée.

Liens pertinents:

Pour une meilleure compréhension, vous pouvez lire ceci R&EACUTE;PONSE

1
Rohit Singh