Android之Handler源码分析(第一篇:创建对象)

前言 

    Handler类定义在android/os/Handler.java文件中,做Android的同学,对Handler一定再熟悉不过……今天一起学习Handler对象的创建代码……

    创建Handler对象,在Handler类中提供7个构造方法,其中3个构造方法可以直接使用,剩余的构造方法为hide修饰,无法直接使用
 

无参构造方法(常用)

    public Handler() {
        this(null, false);
    }

    这是最常用的一个构造方法,在它的方法体内部直接调用了重载的拥有两个参数的构造方法,并传入了一个null、一个false。

null值表示无需回调的Callback对象,false表示创建的Handler对象发送的是同步消息

 

两个参数的构造方法(hide修饰)

    public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

传入的第一个参数为Callback对象,表示用于回调的对象,第二个参数为boolean值,表示此Handler发送的消息类型,传入false值表示同步消息,传入true值表示异步消息……接待下来我们看下构造方法体中执行了哪些代码

1、检查潜在的内存泄漏

FIND_POTENTIAL_LEAKS为一个常量,它的固定值为false,说明检查内存泄漏的代码,只有在debug环境中才启用,看来Google大佬们也有预留的调试代码 ,怎么检测的内存泄漏?这里先不做分析,我们接下来看看业务逻辑

2、获取Looper对象,并开始持有

通过Looper的静态方法myLooper()获得Looper对象,并赋值给Handler对象持有的实例变量mLooper

3、检查获取Looper对象的结果

如果mLooper指向的是null,说明Looper的静态方法myLooper()没有获取到一个Looper对象,通过抛出RuntimeException异常对象,告知用户当前线程中没有创建Looper对象

4、获取Looper对象持有的MessageQueue对象

检查获取Looper对象通过后,接着将Looper对象持有的MessageQueue对象赋值给Handler对象持有的mQueue中,此时说明当前Handler对象开始持有Looper对象持有的MessageQueue对象

5、将传入的Callback对象保存起来

Handler对象持有的实例变量mCallback负责保存传入的Callback对象,每个Callback表示回调的对象

PS:Callback类是定义在Hander类的内部的一个静态内部interface,内部只有一个handleMessage(Message msg)抽象方法

    public interface Callback {
        public boolean handleMessage(Message msg);
    }

6、将传入的消息类型保存起来

Handler对象持有的实例变量mAsynchronous负责保存传入的boolean值,此boolean值表示Handler对象发送消息的类型,消息类型有两种,一个是同步消息、另一个是异步消息(注意:所有设置mAsynchronous状态的构造方法都是hide状态)

 

传入一个boolean值参数的构造方法(@hide修饰)

    public Handler(boolean async) {
        this(null, async);
    }

同样在内部调用的是可传入一个Callback对象、一个boolean值参数的构造方法。传入的null表示无需指定Callback对象,传入的async表示Handler发送消息的类型

 

传入一个Callback对象的构造方法(常用)

    public Handler(Callback callback) {
        this(callback, false);
    }

同样在构造方法的内部调用的是需要的是两个参数的构造方法

 

传入一个Looper对象的构造方法(常用)

    public Handler(Looper looper) {
        this(looper, null, false);
    }

方法内部会调用了三个参数的构造方法,将传入的Looper对象直接传了进去,后面依次传入的Callback为null,消息类型标志位为false,说明创建的Handler发送的消息是同步消息

 

三个参数的构造方法(hide修饰)

    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

1、保存传入的Looper对象

为Handler对象持有的mLooper赋值一个传入的Looper对象

2、保存Looper对象持有的MessageQueue对象

为Handler对象持有的mQueue赋值Looper对象持有的MessageQueue对象,每个Handler对象都会持有Looper对象持有的MessageQueue对象

3、保存传入的Callback对象

Handler对象持有的mCallback赋值为传入的Callback对象

4、保存发送消息的类型

Handler对象持有的mAsynchronous赋值为传入的标志位值async,该值表示该Handler发出的消息类型(true表示异步消息,false表示同步消息)

 

两个参数的构造方法

    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }

方法体内部直接调用了三个参数构造方法,传入的looper、callback直接传了进去、最后一个boolean值传入的是false,说明创建的是发送同步消息的Handler对象

 

总结

1、Handler对象持有一个Looper对象

2、Handler对象也持有了Looper对象持有的MessageQueue对象

3、Handler可持有一个Callback对象,该Callback表示回调的对象,可不传入

4、Handler对象持有一个mAsynchronous标志位,该标志位代表Handler发出的消息类型,true表示异步消息,false表示同步消息

5、Handler对象持有的mAsynchronous标志位,所有相关的构造方法都是hide修饰的,我们想创建异步消息的Handler对象,有两个办法:

第一、使用反射在运行时修改

第二、使用Message对象的setAsynchronous()方法可以设置消息类型(因为mAsynchronous标志位会传递给Message对象,由它来使用)

 

Handler的日常使用方式(自动发送消息,自己处理消息)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值