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在子线程中开启轮询,即可实现子线程自己的消息队列,这点有些类似于线程池
 
posted @ 2015-01-31 00:39  MR.king-wang  阅读(577)  评论(0编辑  收藏  举报