zoukankan      html  css  js  c++  java
  • handler机制详解

    2015年1月30日 13:51:32     晴 

    handler机制详解
    1.     handler机制
      1. 一个Activity启动的时候,先是ActivityManager先为每一个application创建一个ActivityThread,然后调用ActivityThread里面的main方法,其中有一个 代码  
        Looper.prepareMainLooper();
        而Looper类中  Looper.prepareMainLooper();方法调用的是
        public static final void prepare() {
        if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
        }
        从线程级共享对象中设置一个looper对象,如果这个对象已经被创建过,则抛出异常
         
        接下来回到ActivityThread接着看它的main方法
        接下来有一行代码
        Looper.loop();
        Looper类中
        public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
        Message msg = queue.next(); // might block
        //if (!me.mRun) {
        // break;
        //}
        if (msg != null) {
        if (msg.target == null) {
        // No target is a magic identifier for the quit message.
        return;
        }
        if (me.mLogging!= null) me.mLogging.println(
        ">>>>> Dispatching to " + msg.target + " "
        + msg.callback + ": " + msg.what
        );
        msg.target.dispatchMessage(msg);
        if (me.mLogging!= null) me.mLogging.println(
        "<<<<< Finished to " + msg.target + " "
        + msg.callback);
        msg.recycle();
        }
        }
        }
        说明一个Application应用中,主线程ActivityThread一直存在一个looper死循环,
        处理界面更新和activity生命周期及service等操作
         
        还是看它的第一行
        Looper me = myLooper();
         
        接着往下看  myLooper()代码;
        public static final Looper myLooper() {
        return (Looper)sThreadLocal.get();
        }
        从线程级共享对象中获取Looper.prepareMainLooper()
        存入的looper对象,而且因为上面的一个判断,所以每个界面取出来的looper都是相同的;
        这里实现了多个Activity取得都是同一个Looper

      2. 主线程ActivityThread中还有一个点 就是它的handler是它自己自定义的
        private final 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;
        public static final int HIDE_WINDOW = 106;
        public static final int RESUME_ACTIVITY = 107;
        public static final int SEND_RESULT = 108;
        public static final int DESTROY_ACTIVITY = 109;
        public static final int BIND_APPLICATION = 110;
        public static final int EXIT_APPLICATION = 111;
        public static final int NEW_INTENT = 112;
        public static final int RECEIVER = 113;
        public static final int CREATE_SERVICE = 114;
        public static final int SERVICE_ARGS = 115;
        public static final int STOP_SERVICE = 116;
        public static final int REQUEST_THUMBNAIL = 117;
        public static final int CONFIGURATION_CHANGED = 118;
        public static final int CLEAN_UP_CONTEXT = 119;
        public static final int GC_WHEN_IDLE = 120;
        public static final int BIND_SERVICE = 121;
        public static final int UNBIND_SERVICE = 122;
        public static final int DUMP_SERVICE = 123;
        public static final int LOW_MEMORY = 124;
        public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
        public static final int RELAUNCH_ACTIVITY = 126;
        public static final int PROFILER_CONTROL = 127;
        public static final int CREATE_BACKUP_AGENT = 128;
        public static final int DESTROY_BACKUP_AGENT = 129;
        public static final int SUICIDE = 130;
        public static final int REMOVE_PROVIDER = 131;
        public static final int ENABLE_JIT = 132;
        public static final int DISPATCH_PACKAGE_BROADCAST = 133;
        public static final int SCHEDULE_CRASH = 134;
        我们可以看懂很多的状态,当状态改变时发送不同Message的H消息,从而进行相应的处理
      3. 最终总结
        1. 先ActivityThread被ActivityManager创建,然往ThreadLocal里面存一个创建的Looper,接下来执行Loop 一直阻塞操作更新UI和生命周期,用户点击后发消息时,调用的是sendMessageAtTime()方法,然后被放入到消息队列MessageQueue中,等待Looper去next获取,当获取到了时候,looper调用的msg.target的dispatchMessage方法,这个target指的就是与之对应的handler,最后调用的handler的handeMessage方法,实现多线程之间的通讯
        2. 子线程中可以有handler,但是必须有一个与之对应的looper,调用looper.prepare来初始化一个looper,其中在它的构造函数中已经创建了一个与之对应的消息队列MessageQueue,然后调用looper.loop在子线程中开启轮询,即可实现子线程自己的消息队列,这点有些类似于线程池
     
    静以修身 俭以养德
  • 相关阅读:
    C Pointer-to-Function 与 C++ Pointer-to-MemberFunction 的区别
    selenium-webdriver 简单教程
    关于元素不在窗口时如何找到元素
    python-ConfigParser模块【读写配置文件】
    Python定位SVG元素
    Selenium自动化测试Python三:WebDriver进阶
    selenium之 定位以及切换frame(iframe)
    webdriver 的三种等待方式
    Selenium2+python自动化38-显式等待(WebDriverWait)
    selenium webdriver python 元素操作
  • 原文地址:https://www.cnblogs.com/Android-MR-wang/p/4263502.html
Copyright © 2011-2022 走看看