关于静态内部类结合WeakReference避免内存泄露,同时可访问外部类的成员
来源:互联网 发布:c语言浮点数精度控制 编辑:程序博客网 时间:2024/05/22 04:41
- public class BleService extends Service {
- public static final String TAG = "BleService";
- static final int MSG_REGISTER = 1;
- static final int MSG_UNREGISTER = 2;
- private final Messenger mMessenger;
- private final List<Messenger> mClients =
- new LinkedList<Messenger>();
- public BleService() {
- mMessenger = new Messenger(
- new IncomingHandler(this));
- }
- @Override
- public IBinder onBind(Intent intent) {
- return mMessenger.getBinder();
- }
- private static class IncomingHandler extends Handler {
- private final WeakReference<BleService> mService;
- public IncomingHandler(BleService service) {
- mService = new WeakReference<BleService>(service);
- }
- @Override
- public void handleMessage(Message msg) {
- BleService service = mService.get();
- if (service != null) {
- switch (msg.what) {
- case MSG_REGISTER:
- service.mClients.add(msg.replyTo);
- Log.d(TAG, "Registered");
- break;
- case MSG_UNREGISTER:
- service.mClients.remove(msg.replyTo);
- Log.d(TAG, "Unegistered");
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
- }
首先,InnerHandler 声明为静态。不要试图以一个非静态内部类来实现这个,否则会泄漏内存(leaking memory),这可能非常严重。这是因为一个类的非静态内部类可以持有一个该类的实例,并可以直接访问其成员变量和方法。简单来说,Java垃圾收集器将不会破坏被其他对象引用的对象(实际上比这更复杂一点,但也足够解释所发生的情况)。该Handler的父类实例是一个Service对象(一个Android Context),所以如果有任意一个对象持有该Handler实例的引用,都将隐式地阻止该Service对象被垃圾回收掉。这就是所谓的“Context leak (上下文泄漏)”。它也是一个非常糟糕的事情,因为上下文可能相当大。
(译者注:关于“Context Leak”更多的介绍请查看http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html)
我们避免上下文泄漏的方法是始终将内部类声明为静态,if they are declared within classes which subclass Context (不知道该怎么翻译)。 这也意味着我们已经失去了使用内部类的一个主要优点:访问父类属性和(or或)方法的能力。但我们可以很容易地通过使用WeakReference(弱引用)来克服这一点。弱引用可以使我们保持对一个对象的引用,并且不会阻止它被垃圾回收机制回收。
所以我们的InnerHandler类被构造成拥有一个包裹在WeakReference对象中的它父类的实例的引用。而不是直接拥有其父类的引用。这样InnerHandler可以调用 WeakReference 的get()方法获取其父类实例的引用。我们需要做一个null判断因为父类的实例如果被垃圾回收那么该引用将为空,但如果它不为空,那么我们可以以与非静态内部类完全相同的方式使用该实例的引用。
- 关于静态内部类结合WeakReference避免内存泄露,同时可访问外部类的成员
- 关于静态内部类结合WeakReference避免内存泄露,同时可访问外部类的成员
- 关于java内部类访问类的静态成员变量
- 非静态内部类为什么可以访问外部类的静态成员
- 静态内部类无法访问外部类的实例成员
- 内部类访问外部类成员
- Java-内部类(三)成员内部类就应该访问外部类的成员!!
- 外部类能访问内部类的成员
- 外部类可以访问内部类的私有成员
- 为什么内部类可以访问外部类的成员
- Java内部类为什么可以访问外部类的成员
- 关于匿名内部类,非静态内部类会造成内存泄露的隐患。
- 非静态的内部类会持有外部类的一个隐式引用 造成内存泄露
- 静态内部类,成员内部类,外部类之间的一些知识总结
- 内部类,外部类成员的相互访问 及内部类对象的创建
- 内部类之设计模式-内部类可以访问外部类的私有成员
- 内部类之设计模式-内部类可以访问外部类的私有成员
- java 结合内部类与外部类的静态(static)与非静态的用法
- 文科生细谈学习Linux系统的重要性
- 经验分享:C/C++做cifar-10转换成图片
- Symfony学习-01
- JDK/JAVA 1.5到1.9版本特性对比
- 41:判断元素是否存在(编程基础之综合应用)
- 关于静态内部类结合WeakReference避免内存泄露,同时可访问外部类的成员
- Android Studio 多渠道打包、自动版本号及 gradlew 命令的基本使用
- Spring配置Mybatis执行原生SQL语句
- Android正式和开发环境下切换操作,BuildConfig帮你一步到位
- JAVAAPI学习之Calendar类
- 数据延时理论
- SpringMvc整合Activiti网页流程设计器
- MongoDB哈希分片为什么分布不均匀?
- windows txt文件linux下乱码解决办法