Weak link instead of getActivity () (Android avoids memory leak)?

To avoid memory leaks, I wrote the following method, which will be used in actions and mainly in fragments (using inheritance). This method should allow me to never refer directly to activity, causing

//this or getActivity() 

Method:

 private WeakReference<BaseActivity> activityWeakReference = null; public BaseActivity getActivityFromWeakReference(){ activityWeakReference = activityWeakReference == null ? new WeakReference<BaseActivity>((BaseActivity)getActivity()) : activityWeakReference; return activityWeakReference.get(); } 

Is this getActivityFromWeakReference() method instead of getActivity() safe according to the memory leak threat?

If this is unsafe, should I return activityWeakReference and call its get() method to make it safe?

I used it in several fragments, and so far I have not had any problems. I ask a question because I read this ( here ):

As long as the helper's lifespan is during the lifetime of the Activity , then there is no need to use a WeakReference . If the helper can live longer than the Activity , then you should use WeakReference to avoid saving the Activity in the object graph when the system destroys it.

Until now, I have not encountered the case when the mentioned element survived the activity. Please guys, if you find a mistake or a possible one, just write it in the comments.

+5
source share
2 answers

It is quite feasible. For example, you have this pseudo-code:

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new DownloadTask().execute(); } public void showInfo() { } class DownloadTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void data) { // we can call showInfo() activity because Asynctask hold an implicit reference to activity showInfo(); } } } 

The code above will cause a memory leak.

Here is an explanation:

When you create a DownloadTask as shown above, the java call DownloadTask is an inner class . The inner class implicitly contains a reference to the outer class, in this case MainActivity . Moreover, when you run asintasku, this asynthesis will be held by the system until it is completed. For example, loading takes 30 seconds. Within 30 seconds you rotate your device. When the device is rotated, the MainActivity re-created , and often the old activity will be destroyed. But in this case, the old activity is not destroyed, because the old MainActivity instance is held by DownloadTask and DownloadTask is executed by the system. You will skip one instance of the action.

To fix this, you should change the code above:

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new DownloadTask(this).execute(); } public void showInfo() { } } class DownloadTask extends AsyncTask<Void, Void, Void> { WeakReference<MainActivity> mainActivityWeakReference; public DownloadTask(MainActivity activity) { mainActivityWeakReference = new WeakReference<MainActivity>(activity); } @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void data) { if (mainActivityWeakReference.get() != null) { mainActivityWeakReference.get().showInfo(); } } } 

In this case, when a new MainActivity is created, the old one is not held by DownloadTask (due to a weak reference attribute), so the old one will be destroyed by the Android Garbage Collector in the future. You should also check every time you use a weak reference object, because you do not know exactly when the GC will destroy this object.

Here is my own blog about another memory leak situation. Memory leak when using a static inner class

I hope for this help.

+5
source

There is some case if your fragment is set to save the instance, it will be longer than the activity, or if your fragment leaked.

0
source

Source: https://habr.com/ru/post/1270496/


All Articles