1:处理消息的手段————Handler、Looper、MessageQueue          我们知道Android有主线程(UI线程)和子线程,所有的消息队列都会封装成消息在主线程中来处理,为了保证主线程不退出,消息放在一个死循环中如图所示:                       UI线程的循环是在ActivityThread.main方法中创建,    ActivityThread,顾名思义,UI线程,也是Android整个应用的入口,代码如下所示:          
                public static void main(String[] args) {                 //代码省略                 Process.setArgV0("");                 Looper.prepareMainLooper();//1:创建消息循环                 ActivityThread thread = new ActivityThread();                 thread.attach(false);                 if (sMainThreadHandler == null) {                 sMainThreadHandler = thread.getHandler();//线程UI的Handler                 }                 if (false) {                 Looper.myLooper().setMessageLogging(new                 LogPrinter(Log.DEBUG, "ActivityThread"));                 }                 Looper.loop();//2:执行消息循环                 throw new RuntimeException("Main thread loop unexpectedly exited");                 }                   
消息运转的关键————Handler(必须在主线程中创建)创建示例如下:
                   class MyHandler extends Handler {                                        @Override                    public void handleMessage(Message msg) {                    // 更新UI                    }                                        }                              
                      MyHandler mhandler = new MyHandler();                       new Thread(){                       public void run{                       //耗时操作                       mhandler.sendEmptyMessage(123);                       };                       }.start();                             
每个Handler都会关联一个消息队列,消息队列又封装在Looper中,每个Looper又关联一个线程,说白了,Handler就是一个消息处理器,将消息post给消息队列,再由对应的线程逐个取出。那么问题来了,消息队列是如何创建的呢?
答:就是ActivityThread.main中 Looper . prepareMainLooper (); 方法 我们先看如下源码:
                   public Handler(Callback callback, boolean async) {                           //代码省略                    mLooper = Looper.myLooper();//获取Looper                    if (mLooper == null) {                    throw new RuntimeException(                    "Can't create handler inside thread that has not called Looper.prepare()");                    }                    mQueue = mLooper.mQueue;//获取队列                    mCallback = callback;                    mAsynchronous = async;                    }                        Handler构造里面Looper.getLooper()来获取Looper对象并与之关联,它是怎么工作的呢?              下面来看看myLooper里面代码怎么实现的:               
                   public static Looper myLooper() {                    return sThreadLocal.get();                    }                        
接着往下看:
                public static void prepareMainLooper() {                 prepare(false);//见下                 synchronized (Looper.class) {                 if (sMainLooper != null) {                 throw new IllegalStateException(                 "The main Looper has already been prepared.");                 }                 sMainLooper = myLooper();//设置UI线程的Looper为当前Looper对象                 }                 }                   
                   // 为当前线程设置一个Looper                    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));                    }                        
从上面可以看到Looper是通过 sThreadLocal . get (); 获取到的,Looper是什么时候存到 sThreadLocal中的呢?如下:
这样队列就与线程关联上了 前面讲到Handlder与Looper的关联,所以Handler最终和队列、线程就关联上了 这也就解释清楚了:更新UI的时候为什么必须要在主线程中创建Handler,就是因为Handler要与主线程的消息队列进行关联
关联明白了,那么如何循环队列呢:答:通过Handler来Post消息给消息队列 那么消息是如何被处理的呢?我们明天继续分解

更多相关文章

  1. Android深入浅出之Binder机制
  2. [原]采用MQTT协议实现Android消息推送
  3. Android面试系列文章2018之Android部分IntentService机制篇
  4. android 加载图片轻松避免OOM(out of memory)
  5. Android(安卓)Configuration属性解析
  6. 彻底理解android binder通信架构
  7. Android(安卓)之 Looper Handler Message 之间的关系
  8. AsynTask 异步任务
  9. Android开发艺术探索—— 第十一章Android的线程和线程池

随机推荐

  1. Android(安卓)让你的 EditText 只接受指
  2. Android(安卓)菜单(Menu)控件的使用
  3. Android全部源码导入Eclipse
  4. 【Android】Android(安卓)4.2源码下载(ubu
  5. android 中的 Bitmap
  6. android 读取文件内容操作
  7. 安卓巴士Android开发神贴整理
  8. android 调试方法
  9. android中文api (59) —— TabHost.TabSp
  10. Android(安卓)在屏幕上打印LOG