How to pass Context to AsyncTask?
Asked Answered
G

3

21

How to pass context in Async Task class which is coded in different java file from Main Activity but it called from main activity?

Below is my code:

 @Override

protected void onPostExecute(List<Movie_ModelClass> result) {
        super.onPostExecute(result);

        if (result != null) {
            Movie_Adapter movieAdapter = new Movie_Adapter(new MainActivity().getApplicationContext() , R.layout.custom_row, result);
            MainActivity ovj_main = new MainActivity();
            ovj_main.lv_main.setAdapter(movieAdapter);
        } else {
            Toast.makeText(new MainActivity().getApplicationContext() ,"No Data Found", Toast.LENGTH_LONG);

        }
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
    }
Gypsophila answered 30/5, 2016 at 18:35 Comment(0)
W
90

You could just pass a Context instance as a constructor parameter (and keep a WeakReference to it to avoid memory leaks).

For example:

public class ExampleAsyncTask extends AsyncTask {
    private WeakReference<Context> contextRef;

    public ExampleAsyncTask(Context context) {
        contextRef = new WeakReference<>(context);
    }

    @Override
    protected Object doInBackground(Object[] params) {
        // ...
    }

    @Override
    protected void onPostExecute(Object result) {
        Context context = contextRef.get();
        if (context != null) {
            // do whatever you'd like with context
        }
    }
}

And the execution:

new ExampleAsyncTask(aContextInstance).execute();
Wizardry answered 30/5, 2016 at 18:50 Comment(4)
Because you have if (context != null) {, in what case would the context be null?Incorporable
@Incorporable In case the Context gets destroyed during the execution of the AsyncTask. For example the AsyncTask holds a reference to an Activity and an orientation change occurs while doInBackground is executing.Wizardry
but the context could also be destroyed without leaving the activity/orientation changes, only because the GC thinks so, it would happen rarely, but it could happen, and this would be good.Incorporable
Thanks. I was a bit confused by what to do with the context, so I cast it to MainActivity (since that's what calls the task in my case): MainActivity context = (MainActivity)contextRef.get();. And of course it can be also used within 'doInBackground'.Puzzler
R
1

You can just pass the context in the constructor of your AsyncTask.

MyAsyncTask.java

public class MyAsyncTask extends AsyncTask<Void, Integer, List> {

    private final Context mContext;

    public MyAsyncTask(final Context context) {
         mContext = context;
    }
}

and then just use the mContext variable in your onPostExecute() method.

When you call your AsyncTask from your MainActivity, you pass the context to the constructor of MyAsyncTask.

MainActivity.java

final MyAsyncTask task = new MyAsyncTask(getApplicationContext());
task.execute();
Repletion answered 30/5, 2016 at 18:44 Comment(1)
The AsyncTask shouldn't retain a strong reference to the activity context. There are many Q&As about this. Here's one.Marketplace
E
0

I encountered same issue when trying to compress an image using an Async class. I had a constructor in place so I just added context as below

   public BackgroundImageResize(Context context, Bitmap bm) {
    if (bm != null){
        mBitmap = bm;
    }
    this.context =context;
}

Then i called the class like below,

public void uploadDevicePhoto(Uri imageUri){

BackgroundImageResize resize = new BackgroundImageResize(this,null);
resize.execute(imageUri);

}

Expressway answered 8/9, 2019 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.