Contexts, AsyncTask and rotation changes

2020-07-17 06:35发布

问题:

Is it a good practice to use getApplicationContext() working with AsyncTask in order to do not have to attach and detach the Activity to avoid memory leaks when rotation changes occur and the Activity is destroyed? I thing it should be correct, as I actually need a Context that depends on the hole application, not the Activity itself.

And what is more, in those cases in which is better to use the Activity as context (because you need access to the Activity showing)... Instead of detaching it (assigning to null) when it is destroyed and then assign the new instance in onCreate(), could be just avoid detaching? So, just reasigning the new instance, this way, we could avoid problems of NullPointerException because there would always be a context to use!

回答1:

This post and its answers are a good explanation of what to do. This post and its answers explain some good theory behind the AsyncTask and Context issue.



回答2:

From my own experience I can say that in most cases it is better to use Activity as your Context, than getApplicationContext() when dealing with AsyncTask. This is because most of times you will need to access members from your Activity and you will only be allowed to do so if you have a reference to the Activity in your AsyncTask.

To answer my question about avoiding detach(), let me say that in this case you can avoid it or just do it without any problems, as @CommonsWare states in his answer. So, from what he says we are sure that we will not get a NullPointerException while the Activity is null during a rotation change:

onProgressUpdate() and onPostExecute() are suspended between the start of onRetainNonConfigurationInstance() and the end of the subsequent onCreate()

If I am not wrong, the main difference between not detaching explicitly and just re-attaching the new one in the onCreate() of the newly created Activity is that you free the old Activity instance some milliseconds later when just reattaching. But the final behavior is the same in both cases!

Hope this helps someone else! :)