我的一个同事最近提到他们看的一个演讲,其中讲到:
如果你是一个安卓开发者却不使用弱引用,那么你就有麻烦了。
我个人认为这不仅是一种错误观点,而且相当误导人。WeakReference(弱引用)应该是修复内存泄漏的最后手段。
然后今天,我看到了 Enrique López Ma?as 发布在Google Developers Experts专栏的一篇文章。
Finally understanding how references work in Android and Java
A few weeks ago I attended Mobiconf, one of the best conferences for Mobile Developers I had the pleasure to attend in…medium.com
这是一篇总结Java引用的好文章。
这篇文章并没有说必须使用弱引用,但是也没有给出替代的方案。我觉得我必须给出其它的方法来阐明弱引用并不是必须使用。
如果你不使用弱引用并不会真的有什么问题
我认为处处使用弱引用并不是一种最佳实践。使用弱引用来修复内存泄漏的问题往往意味着缺乏合理的架构。
虽然文章中给出的例子修复了潜在的内存泄漏问题,但是也有其它的方法。我可以给出两个耗时后台任务中避免内存泄漏的例子。
避免AsyncTask内存泄漏的简单例子:
Activity:
public class MainActivity extends Activity {
private MyAsyncTask task;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
task = new MyAsyncTask();
task.setListener(createListener());
task.execute();
}
@Override
protected void onDestroy() {
task.setListener(null);
super.onDestroy();
}
private MyAsyncTask.Listener createListener() {
return new MyAsyncTask.Listener() {
@Override
public void onSuccess(Object object) {
// adapt contents
}
};
}
}
这里是AsyncTask:
classMyAsyncTaskextendsAsyncTask{
privateListenerlistener;
@Override
protectedObjectdoInBackground(Object[]params){
returndoSomeStuff();
}
privateObjectdoSomeStuff(){
//dosomethingtogetresult
returnnewObject();
}
@Override
protectedvoidonPostExecute(Objectobject){
if(listener!=null){
listener.onSuccess(object);
}
}
publicvoidsetListener(Listenerlistener){
this.listener=listener;
}
interfaceListener{
voidonSuccess(Objectobject);
}
}
当然这个例子非常基础,但是我认为作为另一种解决方案的演示来说足够了。
这里是另一个使用RxJava实现的简单例子,我们仍然没有使用弱引用。
public class MainActivity extends Activity {
private Subscription subscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
subscription = Observable
.fromCallable(new Callable<Object>() {
@Override
public Object call() throws Exception {
return doSomeStuff();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
// adapt contents
}
});
}
private Object doSomeStuff() {
//do something to get result
return new Object();
}
@Override
protected void onDestroy() {
subscription.unsubscribe();
super.onDestroy();
}
}
注意如果我们没有unsubscribe Subscription那么仍然可能会出现内存泄漏。
最后我给出两个Novoda的项目,它们是很好的学习资源。你可能猜到了,它们并没有使用任何弱引用:)。
novoda/bonfire-firebase-sample
bonfire-firebase-sample - An app to discuss your favourite emojis. This is a sample app built with Firebase.github.com
novoda/spikes
spikes - Where ideas & concepts are born & incubatedgithub.com
我认为一个很重要的守则是让内部类为静态的。尤其是它们要做耗时的后台任务的时候。或者更好的方法是把这个类移到外面作为单独的类。
用非静态的内部类做耗时的后台任务总是很糟糕的实践,不光是在安卓中。
你并不一定要用弱引用来避免内存泄漏
发表于:2017-01-09
作者:网络转载
来源:
 相关文章
薪资翻3倍,软件测试面试 (3 轮技术... 软件测试之什么是测试计划? 人工智能软件测试2024年主要趋势 去测试化真的可行吗? 为什么微服务的测试必须左移 漫谈测试成长之探索——测试排期- 周排行
- 月排行
-   接口自动化测试做到什么程度的覆盖算...
-   软件测试经验总结之软件测试的痛点有...
-   听起来很玄乎的CPU测试,一篇文章弄清...
-   集成测试:开发人员为何关注它
-   软件测试中桩模块与驱动模块
-   一文搞懂企业渗透测试
-   物联网测试:方法、挑战和工具
-   程序开发人员的自测要求规范
-   接口自动化测试做到什么程度的覆盖算...
-   从 Facebook 的分析面试题来看如何...
-   软件测试中桩模块与驱动模块
-   软件测试中的AI应用地图
-   听起来很玄乎的CPU测试,一篇文章弄清...
-   软件测试经验总结之软件测试的痛点有...