Question

I am pretty new to async tasks, but the few I have created for my app entail accessing class level variables and I have had a few null pointer exceptions sometimes in the doInBackground() for these tasks on real-world devices.

I believe this is because these variables should not really ever be accessed from within the async task, but instead passed in through the constructor or params etc. For example if I transition to activity B and an async task is still running from activity A, all of A's variables should become null shouldn't they?

And if accessing these variables should never be used from within the context of an async task, shouldn't the IDE (Android Studio in my case) warn me this is a dangerous action?

Edit: Wow so much help so quickly! Hopefully this will help others in the future too. Here is some code which is roughly what I was thinking about:

public class MyActivity extends ActionBarActivity {

private Context mContext;
private User mUser;
private ProgressDialog mProgressDialog;

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   mContext = this;
   mProgressDialog = new ProgressDialog(mContext);
   mUser = new User();
   new MyAsyncTask.execute();
}


private class MyAsyncTask extends AsyncTask<Params, Integer, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog.setIndeterminate(true);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setCancelable(true);
        mProgressDialog.setMessage("My message");
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
    }

    @Override
    protected Void doInBackground(Params... params) {
        Toast.makeText(mContext, "In doInBackground()", Toast.LENGTH_LONG).show();
        mUser.someMethodThatTakesTime();
        return null;
    }

     @Override
    protected void onPostExecute(Void params) {
        mProgressDialog.dismiss();
        //Possibly launch another activity
    }
 }
}
Was it helpful?

Solution

You should definitely avoid using AsyncTask as an Inner Class in your Activity. Inner classes contain implicit strong references to their container class, so you run the risk of getting null pointers like you experienced during the Activity Lifecycle. And it does not just happen if Activity B goes on top of Activity A. It could happen if you rotate the device as well.

The problem is the Activity Lifecycle (which is why your IDE is not giving you warnings). For a configuration change (such as rotation), or in low memory situations, the Activity can be destroyed and recreated. But your AsyncTask will still be tied to the old activity.

There are a lot of threads about this:

https://stackoverflow.com/a/8550351/1856960

https://stackoverflow.com/a/16305144/1856960

You can also look into third party frameworks designed to deal with this:

https://github.com/stephanenicolas/robospice

Google around for more info too, this is hardly an exhaustive list.

OTHER TIPS

I provide you two links. firstly read and try to understanding I expected that you will solve any problem about Android Asynctask problems in future.

link 1 Android Asynctask Example

and link 2 Android Background Processing with Handlers and AsyncTask and Loaders - Tutorial

Best of Luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top