I need to reference an activity in several static methods. I’m curious to know the best practices to avoid memory leaks. Let’s use examples:
Example 1:
static void hideKeyboard(Activity activity) { WeakReference<Activity> activityReference = new WeakReference<>(activity); // ... Call activityReference.get() when needed, check if null... }
Example 2:
static void hideKeyboard(WeakReference<Activity> activityReference) { // ... Call activityReference.get() when needed, check if null... }
So three questions:
- Do example 1 or 2 make any difference?
- I haven’t seen methods being called this way much outside of subclasses of
Thread
orAsyncTask
. Any reason why? Am I missing something? - If the weak reference is used in a
Thread
orAsyncTask
inside one of those methods, could memory still leak?
Advertisement
Answer
No, it doesn’t make a difference. Garbage collection in Java works on the idea of GC roots. If a variable is a GC root or references by a GC root (including transitively) it cannot be garbage collected. Parameters to a function are a GC root- until the function returns none of its parameters can be collected. Since Activity is a parameter to your function, it will be uncollectable as long as that function is in the call stack. Using a WeakReference won’t speed it up.
Threads and AsyncTasks (which are just wrappers around Thread really) are slightly different. Every running thread is also a GC root. But threads can have a long lifetime and exist beyond the lifecycle of the object. Here, using a WeakReference does possibly help because there isn’t another reason it needs to be kept around (like the parameter in your sample).
Your example 2 is a bit better, it isn’t blatantly unnecessary. But I question why its needed. In general when doing a Thread the pattern should be:
run() { do_async_work() update_ui() } update_ui() { Activity activity = weakReference.get() if(activity == null) { return } //update the UI }
Doing it like this will prevent a lot of problems like needing to check the weak reference a dozen times.