WeakReference 在android中的应用

摘要:
2: 使用静态内部类通过WeakReference实现对活动的弱引用。

首先我们来看一段代码:

public class AutoActivity extends Activity {

    Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auto);
    }
}

       上面这段代码没有什么问题,但是在handler对象创建的时候却会报警告:This Handler class should be static or leaks might occur意思是:Handler

类应该为static类型,否则可能会造成内存泄漏。为什么会造成这种情况呢?这种情况就是由于android的特殊机制造成的:当一个android主线程被创

建的时候,同时会有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我们创建一个handler对象时,而handler的

作用就是放入和取出消息从这个消息队列中,每当我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。因此当

Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg持有handler的引用,而handler在Activity中创建,会持有Activity的引用,

因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。

        这个根本原因就是:Activity在被结束之后,MessageQueue并不会随之被结束,如果这个消息队列中存在msg,则导致持有handler的引用,但是又

由于Activity被结束了,msg无法被处理,从而导致永久持有handler对象,handler永久持有Activity对象,于是发生内存泄漏。但是为什么为static类型就

会解决这个问题呢?因为在java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持

有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。(至于为什么强引用不能够被gc自动回收,而

弱引用对象为什么会被gc回收,可以自行去google)。

所以解决这个警告就有几种方法:

一:将hanlder对象声明为静态的对象。

二:使用静态内部类,通过WeakReference实现对Activity的弱引用。具体实现看以下代码:

public class AutoActivity extends Activity {
    
    MyHandler handler = new MyHandler(this);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auto);
    }
    
    static class MyHandler extends Handler{
        WeakReference<AutoActivity> mactivity;
        
        public MyHandler(AutoActivity activity){
            mactivity = new WeakReference<AutoActivity>(activity);
        }
        
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);            
            switch (msg.what) {
            case 100:                
                //在这里面处理msg
                //通过mactivity.get()获取Activity的引用(即上下文context)
                break;                
            default:
                break;
            }
        }
    }
}

免责声明:文章转载自《WeakReference 在android中的应用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇springboot thymeleaf ----服务端渲染htmlsharepoint内置字段类型下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Netty中的这些知识点,你需要知道!

一、Channel Channel是一个接口,而且是一个很大的接口,我们称之为“大而全”,囊括了server端及client端接口所需要的接口。 Channel是一个门面,封装了包括网络I/O及相关的所有操作。 Channel聚合了包括网络读写、链路管理、网络连接信息、获取EventLoop、Pipeline等相关功能类;统一分配,调度实现相应场景的功能。...

MySQL-快速入门(8)存储过程、存储函数

1、存储过程 1》创建存储过程:create procedure create procedure sp_name ([in | out | inout]param_name type) [characteristics ...] routine_body characteristics指定存储过程的特性: 1>language sql:说明rou...

Android学习笔记十:异步处理

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html 一:基础概念 UI线程:当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件、屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。主线程通常又被称为...

Netty(4)Stream by codec(粘包与拆包)

TCP/IP,传输的是byte[],将byte[]放入队列中。可能会发生粘包和拆包。 比如,客户端向服务端发送了2条消息,分别为D1,D2,可能产生的情况,如下图所示: 情况一:正常的。 情况二:粘包。 情况三:拆包。即:部分数据不是一次完整发送的,而是分了至少2次发送。 如本例,D2拆成了D2_1和D2_2,这是拆包。 服务端分2次收到包,第一次收到了...

Disruptor与Netty实现百万级(十)

实体对象: import java.io.Serializable; public class TranslatorData implements Serializable { private static final long serialVersionUID = 8763561286199081881L; private St...

Android 的窗口管理系统 (View, Canvas, WindowManager)

http://blog.csdn.net/ritterliu/article/details/39295271 From漫天尘沙 在图解Android - Zygote 和 System Server 启动分析一 文里,我们已经知道Android 应用程序是怎么创建出来的,大概的流程是 ActivityManagerService -> Zygote...