Max*_*ude 7 java android memory-leaks weak-references
为了避免内存泄漏,我编写了以下方法,该方法将用于活动,主要用于片段(使用继承).该方法应该允许我永远不会通过调用直接引用该活动
//this or getActivity()
Run Code Online (Sandbox Code Playgroud)
方法是:
private WeakReference<BaseActivity> activityWeakReference = null;
public BaseActivity getActivityFromWeakReference(){
activityWeakReference = activityWeakReference == null ?
new WeakReference<BaseActivity>((BaseActivity)getActivity()) :
activityWeakReference;
return activityWeakReference.get();
}
Run Code Online (Sandbox Code Playgroud)
根据内存泄漏威胁调用此方法getActivityFromWeakReference()而不是getActivity()安全吗?
如果这样做不安全,我应该返回activityWeakReference并调用其get()方法,以确保安全吗?
我一直在使用多个片段,到目前为止我没有任何问题.我问这个问题是因为我读到了这里(这里):
只要帮助者的生命周期在生命周期内
Activity,就没有必要使用WeakReference.如果帮助程序的寿命可以长于Activity,那么您应该使用aWeakReference来避免Activity在系统破坏时保留对象图.
到目前为止,我还没有遇到一个被提及的元素超过活动的情况.如果您发现错误或可能的错误,请在评论中写下.
这完全可行.例如,你有这个伪代码代码:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,有一种情况会导致内存泄漏.
这是解释:
当您DownloadTask按上面的示例创建时,java调用DownloadTask是一个内部类.内部类将隐式保存对外部类的引用,在本例中为MainActivity.而且,当你启动asynctask时,asynctask将由系统保存直到完成.例如,您下载需要30秒.在30秒内,您可以旋转设备.旋转设备时,MainActivity会重新创建设备,并且通常会破坏旧活动.但是,在这种情况下,因为旧如旧的活性不被破坏,MainActivity例如通过持有DownloadTask和DownloadTask通过系统举行.您将泄漏一个活动实例.
要解决此问题,您应该将以上代码更改为:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当MainActivity创建new时,旧的不被保持DownloadTask(由于弱引用属性),因此旧的将在未来被Android垃圾收集器销毁.您还应该在每次使用弱引用对象时进行检查,因为您不确切知道GC何时会破坏这些对象.
这是我自己的博客关于内存泄漏的另一种情况.使用静态内部类时内存泄漏
希望这有帮助.
| 归档时间: |
|
| 查看次数: |
2849 次 |
| 最近记录: |