You don’t have to use WeakReference to avoid memory leaks
来源:互联网 发布:mac pro 必备软件 编辑:程序博客网 时间:2024/05/16 18:25
原文地址:https://medium.com/google-developer-experts/weakreference-in-android-dd1e66b9be9d#.n8z6g146q
我的一个同事最近提到他们看到一种观点说:
如果你是一个Android开发者但你没有使用WeakReferences,那么你就有问题。
我个人认为这不仅是一个错误的观点,也是百分百的误导。WeakReference应该是修复内存泄漏的最后手段。
今天我看了一篇Google开发专家Enrique López Mañas的文章
Finally understanding how references work in Android and Java
这是一篇很好的文章,它通过举例总结了引用在Java中是如何运作的。
文章中既没有说我们必须要使用WeakReference,也没有给出任何替代的方案。我觉得我需要提供一个替代方案来说明WeakReference不是必须的。
就算你没有使用WeakReference,你也没有任何问题。
我相信在任何可能的地方都使用WeakReference并不是最好的方式。使用WeakReference来修复内存泄漏表明了模型或架构中有缺陷。
虽然给出的文章中的例子修复了潜在的内存泄漏,但这还有其他的方式。我会给出两个当你有一个长时的后台任务时如何避免内存泄漏的实例。
一个使用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:
class MyAsyncTask extends AsyncTask { private Listener listener; @Override protected Object doInBackground(Object[] params) { return doSomeStuff(); } private Object doSomeStuff() { //do something to get result return new Object(); } @Override protected void onPostExecute(Object object) { if (listener != null) { listener.onSuccess(object); } } public void setListener(Listener listener) { this.listener = listener; } interface Listener { void onSuccess(Object object); }}
当然这种方式非常基础,但我认为它足够用来展示另一种解决办法。
这里是另一种使用RxJava的简单实现,我们依然没有使用WeakReference。
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(); }}
需要注意的是如果我们没有取消订阅Subscription的话依然会有内存泄漏的情况。
最后我想列举一些Novoda中的示例项目。它们有很棒的资源可以学习。如你所料,它们都没有使用任何WeakReference :)
novoda/bonfire-firebase-sample
novoda/spikes
我相信将内部类设置为静态类是第一原则(就我而言)。特别是如果它们要在后台进行长时间操作时。最好的办法,我们可以将这些类变成完整的类。
使用非静态的内部类来执行长时操作永远是一个坏习惯,不仅仅限于Android。
- You don’t have to use WeakReference to avoid memory leaks
- You don't have permission to access
- You don't have time to fiddle with administrivia.
- You don't have permission to access / on this server
- You don't have permission to access /*** on this server
- Wamp 报403 You don't have permission to access
- Error: You don't have permission to access that port.
- you don't have permission to access /xxx/xxx解决
- You don't have permission to access / on this server.
- You don't have permission to access on this server.
- 嵌入式 apache出现You don't have permission to access
- Forbidden You don''t have permission to access
- You don't have permission to access / on this server.
- WAMP You don't have permission to access
- You don't have permission to access ××× on this server.
- You don't have permission to access / on this server
- Wamp 报403 You don't have permission to access
- You don't have permission to access / on this server.
- Android学习25
- Ceph实战入门系列(二)——块设备
- java导入项目遇见的问题(MyEclipse开发工具)
- Android学习26
- 算法提高 逆序排列
- You don’t have to use WeakReference to avoid memory leaks
- redis配置文件redis.conf
- SpringBoot Controller找不到视图路径
- 【集合】Java集合对比
- 乐乐音乐4.0简洁版
- 二分查找
- maven可用国内镜像 阿里云 飞速下载
- Android学习27
- PAT-A-1002. A+B for Polynomials