Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call parent activity function from ASyncTask?

setAccountAuthenticatorResult can be called from the Activity, which extends AccountAuthenticatorActivity. My activity extends that, but launches ASyncTask and hence this setAccountAuthenticatorResult should be called from ASyncTask (or, the result of ASyncTask should be passed back to the main thread).

How to do it?

What is wrong in the code below?

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

    }
like image 992
LA_ Avatar asked Apr 02 '11 13:04

LA_


2 Answers

When you create the AsyncTask, you can add a new constructor to it, and pass in a reference to the Activity:

AsyncTask myTask = new MyTask(this);

And then from the onPostExecute() method in the AsyncTask you can call the method on the Activity.

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();
    }
}
like image 85
Ollie C Avatar answered Oct 31 '22 12:10

Ollie C


Use Interface

Follow these steps:

1) Create an interface

public interface AsyncTaskListener{

   public void updateResult(String result);

}

2) Use the listener in your 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) Implement the interface in your Activity and Override the interface method

  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 of using interface?

This seems a lengthy approach at first but if you use this approach

You can make a loosely coupled AsyncTask. Which means you can use same AsyncTask with any Activity in Future without even changing code in your AsyncTask.

Relevant Links:

For better understanding you can read this ANSWER

like image 3
Rohit Singh Avatar answered Oct 31 '22 11:10

Rohit Singh