Weak Reference Instead Of Getactivity() (android Avoid Memory Leak)?
Solution 1:
It is totally feasible. For example you have this pseudocode code:
publicclassMainActivityextendsActivity {
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDownloadTask().execute();
}
publicvoidshowInfo() {
}
classDownloadTaskextendsAsyncTask<Void, Void, Void> {
@OverrideprotectedVoiddoInBackground(Void... params) {
returnnull;
}
@OverrideprotectedvoidonPostExecute(Void data) {
// we can call showInfo() activity because Asynctask hold an implicit reference to activity showInfo();
}
}
}
On above code, there is a situation will caused memory leak.
Here is the explanation:
When you create DownloadTask
as above example, java call DownloadTask
is an inner class. An inner class will implicit holds a reference to outer class, in this case is MainActivity
. Moreover, when you start an asynctask, that asynctask will be held by system until it finish. For example, you download takes 30 seconds. In that 30 seconds, you rotate your device. When you rotate your device, MainActivity
is re-created and often old activity will be destroyed. But in this case old activity isn't destroyed because the old MainActivity
instance is held by DownloadTask
and DownloadTask
is hold by system. You will leak one activity instance.
For fixing this, you should change above code to:
publicclassMainActivityextendsActivity {
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDownloadTask(this).execute();
}
publicvoidshowInfo() {
}
}
classDownloadTaskextendsAsyncTask<Void, Void, Void> {
WeakReference<MainActivity> mainActivityWeakReference;
publicDownloadTask(MainActivity activity) {
mainActivityWeakReference = newWeakReference<MainActivity>(activity);
}
@OverrideprotectedVoiddoInBackground(Void... params) {
returnnull;
}
@OverrideprotectedvoidonPostExecute(Void data) {
if (mainActivityWeakReference.get() != null) {
mainActivityWeakReference.get().showInfo();
}
}
}
In this case, when new MainActivity
is created, the old one isn't held by DownloadTask
(due to weak reference attribute), so the old one will be destroyed by Android Garbage Collector in future. You also should to check every time you use a weak reference object, because you don't know exactly when GC will destroyed those object.
Here is my own blog about another situation of memory leak. Memory leak when using static inner class
Hope this help.
Solution 2:
There are some case, if your fragment is set to retain instance, it'll be longer than activity, or if your fragment is leaked.
Post a Comment for "Weak Reference Instead Of Getactivity() (android Avoid Memory Leak)?"