Handler的前世今生之framework层源码分析

Handler在线程间通讯随处可见,尤其framework层,Activity的生命周期就是AMS(ActivityManagerService)通过ApplicationThread(ActivityThread的内部类,也是一个Binder)发送Handler消息通知执行ActivityThread的相应的Activity生命周期函数。那就先来分析一下App点击运行后Handler如何执行Activity的生命周期的,当手指点击手机屏幕上的app图标时,Launcher(其实就是一个Activity,在SystemServer进程初始化后,由Zygote孵化的第一个系统进程)根据点击的图标通过AMS、PMS(Package Manager Services)来完成新App进程的创建,在创建过程中就会启动ActivityThread的main()方法,来看一下main()中做了什么:

    public static void main(String[] args) {

       // 省略部分代码

        Looper.prepareMainLooper();  //【1.0】

        ActivityThread thread = new ActivityThread();
        thread.attach(false);// 【1.1】

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();// 【1.2】
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop(); //【1.3】

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

【1.0】就是主线程开始创建Lopper,这就是为什么我们在UI线程不需要写Loop.prepare()和Lopper.loop()代码,因为ActivityThread已经在App进程创建的时候帮我们完成了,ActivtyThread不是Thread类,只是默认的线程,所以以后她也就代表的main线程(UI 线程),看一下这句代码如何创建主线程的Looper:

   public static void prepareMainLooper() {
        prepare(false); // 【2.1】
        synchronized (Looper.class) {// 加同步对象锁 避免多线程执行
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();//【2.2】
        }
    }

【2.1】真正创主线程的sMainLooper:

 private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed)); // 【3.1】创建一个Looper,存到TLS(Thread Local Storge),也就是存在了Main线程的线程本地存储区
    }

【3.1】创建一个Lopper对象存储到ActivityThread所代表的的UI线程的存储区,以后就直接通过一下代码获取:

public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper; // 该变量为私有的静态变量
        }
    }

方便查看,再写一遍ActivityThread 的Main()吧:

   public static void main(String[] args) {

       // 省略部分代码

        Looper.prepareMainLooper();  //【1.0】

        ActivityThread thread = new ActivityThread();
        thread.attach(false);// 【1.1】

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();// 【1.2】
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Looper.loop(); //【1.3】

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

【1.1】 用来关联AMS,通过Binder机制来与接受AMS的消息
【1.2】获取ActivityThread中的成员变量mH,(Handler)

   final H mH = new H(); // 作为Activity的成员变量,处理ActivityThread接受的消息
       private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
        public static final int STOP_ACTIVITY_SHOW      = 103;
        public static final int STOP_ACTIVITY_HIDE      = 104;
        public static final int SHOW_WINDOW             = 105;
        ...

        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
                switch (code) {
                    case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
                    case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
                    case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
                    case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
                    case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
                     ...

                }
            }
            return Integer.toString(code);
        }
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {

                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");

                } break;

                case PAUSE_ACTIVITY: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();

                } break;
                ...
        }

【1.3】开始循环获取MessageQueue(存储Message的一个类似栈的数据结构)
开始分析循环前,来了解一下这几个类之间的关系:

Looper:

轮询器,该对象每个Thread最多存在一个,UI线程在App创建时在ActivityThread中自动完成,其他线程需要调用Looper.prepare()来为当前线程创建一个Looper,如果该线程已经存在,则不会再创建。

MessageQueue

消息队列,作为消息(Message)的承载体,内部维持一个类似栈的Message集合

Message

消息 ,发送体对象,持有发送者(Handler)的引用,内部含有几个成员变量(arg1,arg2
,what…)内部包含一个Message缓存池,通过obtain()来获取空闲的Message对象,避免重复创建对象

Handler

处理器,消息的发送者,内部持有Looper和MessageQueue对象,创建Handler对象的时候会判断该线程是否存在Lopper和MessageQueue,其实有Lopper就一定存在MessageQueue,因为在创建Looper时候就创建了Looper:

    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

而在创建Handler对象的时候包含多个构造函数:Handler构造函数

其实就是包含三个参数,1:Looper 可以指定一个特定线程持有的Looper,发送的消息将发送到该Looper的MessageQueue 2:CallBack 消息的回调接口

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

3:Boolean 表示是否消息是否异步处理

这下看一下Loop.loop()到底做了什么:

public static void loop() {
    final Looper me = myLooper();  //获取TLS存储的Looper对象 
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;  //获取Looper对象中的消息队列

    Binder.clearCallingIdentity();
    //确保在权限检查时基于本地进程,而不是基于最初调用进程。
    final long ident = Binder.clearCallingIdentity();

    for (;;) { //进入loop的主循环方法
        Message msg = queue.next(); //可能会阻塞 
        if (msg == null) { //没有消息,则退出循环
            return;
        }

        Printer logging = me.mLogging;  //默认为null,可通过setMessageLogging()方法来指定输出,用于debug功能
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }
        msg.target.dispatchMessage(msg); //用于分发Message 
        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }

        final long newIdent = Binder.clearCallingIdentity(); //确保分发过程中identity不会损坏
        if (ident != newIdent) {
             //打印identity改变的log,在分发消息过程中是不希望身份被改变的。
        }
        msg.recycleUnchecked();  //将Message放入消息池 
}

最后,来看一下这个图加深理解:
Handler类关系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值