To mitigate memory leaks we keep a weak reference of an activity in an inner class running on different thread. We check weakreference.get() is non null and then only proceed further. What if when we checked weakreference.get() was non null but garbage collection happened, do we need to check if the reference is non null again and again or am I missing something?
public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyAsyncTask(this).execute();
}
private static class MyAsyncTask extends AsyncTask {
private WeakReference<MainActivity> mainActivity;
public MyAsyncTask(MainActivity mainActivity) {
this.mainActivity = new WeakReference<>(mainActivity);
}
@Override
protected Object doInBackground(Object[] params) {
return doSomeStuff();
}
@Override
protected void onPostExecute(Object object) {
super.onPostExecute(object);
if (mainActivity.get() != null){
//do something
//context switching and garbage collection happen
//again do a null check?
}
}
}
}
What you should do is this:
MainActivity temp = mainActivity.get();
if (temp != null){
// Use 'temp' to access the `MainActivity`
}
Assuming that temp
is not null
, the fact that you now have a regular reference for the MainActivity
object in a live variable means that the object is strongly reachable. The garbage collector won't collect it.
(Indeed, the GC won't break your WeakReference
so long as temp
is still reachable. The specs state that the GC will not break the ref in a (reachable) Reference
if the target of the ref is strongly reachable.)
But the flip-side is that if you don't have a strong reference to the MainActivity
then the GC could break the WeakReference
at any time. So, you should always check the result of the get()
call.