0

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?
            }
        }
    }
}
CodeWithVikas
  • 1,105
  • 9
  • 33
Harsh Yadav
  • 168
  • 12

2 Answers2

2

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • So from this, first create a strong reference and then do a null check. Another caveat is to avoid time consuming operations in the if block to quickly release the reference to avoid stopping of it from GC collected, am I correct? – Harsh Yadav Jun 13 '21 at 06:39
  • And one more thing if the activity is in illegal state or may go in illegal state even though we have a strong reference, how to avoid that? – Harsh Yadav Jun 13 '21 at 06:50
  • 1) Yes. 2) Probably no. If you need the `MainActivity` for some purpose, then it is going to be better to hang onto the strong reference for a longer time than to have to go through all of the hassle of reinstantiating it. 3) Having a strong or a weak reference has no bearing on that. Neither can avoid the the activity going into an illegal state. – Stephen C Jun 13 '21 at 07:14
  • can an activity go in some other state when I am holding a reference to it? – Harsh Yadav Jul 14 '21 at 15:27
  • Holding a reference won't stop an activity changing state. – Stephen C Jul 14 '21 at 15:33
  • In that case how do we ensure that a block of code does not execute if state changes in between execution of that code? Assuming we are executing code on the UI thread even then can state of an activity change – Harsh Yadav Jul 14 '21 at 16:58
  • Have the block of code test the state? This is all rather hypothetical here ... – Stephen C Jul 14 '21 at 22:42
0

You should check not-null-state each access to your variable. But... there is an additional problem, you have to consider the activity state before doing something with it (I mean the lifecycle state).

Maxim Firsoff
  • 2,038
  • 22
  • 28
  • Thanks for mentioning the state but even if after I check and it's not null even then also does it may get collected when reference is used again(after check) right? Or the question can GC be kicked in between two high level instruction calls? – Harsh Yadav Jun 13 '21 at 06:13