看了这么多的文章,终于看懂了。
参考文献: 【1】 androiddeveloper handler 【2】 Android中Handler作用 【3】

Android Thread Looper Handler 关系 【4】 android的消息处理机制(图+源码分析)——Looper,Handler,Message


1、从定义上理解Handler
首先有一下参考文献【1】中的一句英文句子来说明下: A Handler allows you to send and processMessageand Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue. ——以上简单来说,就是每个Handler的实例创建的时候都会关联一个 线程和线程的的 消息队列,并且Handler运行发送和执行Message和Runnable对象。(如果后面半句没理解,没事,请继续往下看)
Scheduling messages is accomplished with the post(Runnable) , postAtTime(Runnable, long) , postDelayed(Runnable, long) , sendEmptyMessage(int) , sendMessage(Message) , sendMessageAtTime(Message, long) , and sendMessageDelayed(Message, long) methods. ——这段仅仅是说明了,有这多方法可以使用,归纳来说就是一个post()和一个sendMessage()方法,这里主要是讲如何向消息队列发送消息。(这段不管)
The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received ; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler). ——【精华】这段主要讲,接受出来。post的Runnable对象将会插入消息队列,之后将会被关联的线程调用执行;使用 sendMessage 将包含 bundle of data 的message插入到消息队列中,通过 handleMessage(Message) 这个函数来获取其值。
说白了,通过Handler可以在两个线程中实现通信。 为什么要使用 Handler ,举个简单的例子,Android的UI主线程只有一个,如果在UI线程中执行网络操作等十分费时操作,将会影响APP的流程度,并且Android系统存在若APP在5秒内不能响应用户的操作,将认为运行不顺,弹出阻止程序运行的窗口。


2、示例程序 2.1 post 示例程序
 public class NasaDaliyImage extends Activity {          public IotdHandler handler;          private ProgressDialog dialog;          private  Handler handlerRun ;          @Override         public void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);             setContentView(R.layout.activity_nasa_daliy_image);             handlerRun =new Handler();//将Handler关联至UI线程             refreshFromFeed();         }         private void refreshFromFeed() {             // doSomeThing 可执行UI操作             Thread th = new Thread() {  //新建线程                  public void run() {                          //执行耗时的网络操作等                          handlerRun.post( // post  Runnable对象                              new Runnable () { //实现Runnable接口                                    public void run() { //重写Runnable的run()方法                                        //执行UI操作                                    }                             }                    );            }        };        th.start(); //线程启动    }

2.2 sendMessage示例程序 根据参考文献【2】得到如下代码 2.2.1 创建Handler实现类,在主UI所在类中的内部类

class MyHandler extends Handler {            public MyHandler() {            }           public MyHandler(Looper L) {                super(L); //Use the provided Looper instead of the default one.          }           // 重写handleMessage方法,接受数据并更新UI          @Override           public void handleMessage(Message msg) {                super.handleMessage(msg);                //此处根据msg内容进行UI操作         }      }     // 在UI线程中执行 MyHandler handler = new MyHandler();不带参数将默认管理UI线程。


2.2.2 子线程的实现

class MyThread implements Runnable {                public void run() {                    //执行费时的操作                    Message msg = new Message();                   Bundle b = new Bundle();                  b.putString("cmd", "update");                   msg.setData(b);                   MainActivity.this.myHandler.sendMessage(msg);//通知Handler更新UI   MainActivity为其主线程              }           }


3、Android Thread Looper Handler 关系

参考文献【3】具体如下: Thread,A Thread is a concurrent unit of execution 线程是一个并发的执行单位。

Looper,Class used to run a message loop for a thread. 维护线程的消息循环类。
Handler,A Handler allows you to send and process Message and Runnableobjects associated with a thread's MessageQueue。 向消息队列发送消息(Runnable object),或者执行消息队列的消息(Runnable object).
其中三者之间的关系见下图(图片来自【4】):


从上图中,可以了解到在一个Main Thread中包含一个Looper,并且Looper包含一个消息队列,在将一个Handler MyHandler关联至Main Thread 在Worker Thread中sendMessage 或者 post至消息队列中,之后由管理消息队列的Looper将其取出,如果是Runnable则进行执行,如果是Message则 调用相应的Handler的 handleMessage 来获取。

下面介绍下Looper


looper启动例程序如下:

public class LooperThread extends Thread {    private Handler handler1;    private Handler handler2;    @Override    public void run() {        // 将当前线程初始化为Looper线程        Looper.prepare();                // 实例化两个handler        handler1 = new Handler();        handler2 = new Handler();                // 开始循环处理消息队列        Looper.loop();    }}


其中app启动Activity的源代码也有相应的代码:

ActivityThread.java public static final void main(String[] args) {    Looper.prepareMainLooper();    ActivityThread thread = new ActivityThread();        thread.attach(false);        // 这里闭合消息循环        Looper.loop();}

其中Looper.loop();是looper不断的读取队列中的消息

之后在\sdk\sources\android-16\android\os\的Looper.java中的 public static void loop()中可以大致看到如下代码,参考【4】 获取消息,并通过调用 dispatchMessage (msg)函数来处理消息

public static final void loop() {        Looper me = myLooper();  //得到当前线程Looper        MessageQueue queue = me.mQueue;  //得到当前looper的MQ                // 这两行没看懂= = 不过不影响理解        Binder.clearCallingIdentity();        final long ident = Binder.clearCallingIdentity();        // 开始循环        while (true) {            Message msg = queue.next(); // 取出message            if (msg != null) {                if (msg.target == null) {                    // message没有target为结束信号,退出循环                    return;                }                // 日志。。。                if (me.mLogging!= null) me.mLogging.println(                        ">>>>> Dispatching to " + msg.target + " "                        + msg.callback + ": " + msg.what                        );                // 非常重要!将真正的处理工作交给message的target,即后面要讲的handler                msg.target.dispatchMessage(msg);                // 还是日志。。。                if (me.mLogging!= null) me.mLogging.println(                        "<<<<< Finished to    " + msg.target + " "                        + msg.callback);                                // 下面没看懂,同样不影响理解                final long newIdent = Binder.clearCallingIdentity();                if (ident != newIdent) {                    Log.wtf("Looper", "Thread identity changed from 0x"                            + Long.toHexString(ident) + " to 0x"                            + Long.toHexString(newIdent) + " while dispatching to "                            + msg.target.getClass().getName() + " "                            + msg.callback + " what=" + msg.what);                }                // 回收message资源                msg.recycle();            }        }    }


再次查看位于 \sdk\sources\android-16\android\os\Handler.java中的 dispatchMessage函数,分别执行Runnable或者调用 handleMessage进行处理。


// 处理消息,该方法由looper调用    public void dispatchMessage(Message msg) {        if (msg.callback != null) {            // 如果message设置了callback,即runnable消息,处理callback!            handleCallback(msg);        } else {            // 如果handler本身设置了callback,则执行callback            if (mCallback != null) {                 /* 这种方法允许让activity等来实现Handler.Callback接口,避免了自己编写handler重写handleMessage方法。                if (mCallback.handleMessage(msg)) {                    return;                }            }            // 如果message没有callback,则调用handler的钩子方法handleMessage            handleMessage(msg);        }    }        // 处理runnable消息    private final void handleCallback(Message message) {        message.callback.run();  //直接调用run方法!    }    // 由子类实现的钩子方法    public void handleMessage(Message msg) {    }


参考文献: 【1】 androiddeveloper handler 【2】 Android中Handler作用 【3】

Android Thread Looper Handler 关系 【4】 android的消息处理机制(图+源码分析)——Looper,Handler,Message






更多相关文章

  1. 线程安全
  2. Android(安卓)性能优化实例
  3. Android的bitmap和优化
  4. Android中循环的几种方式
  5. android 学习之---Android之SurfaceView学习(一)
  6. Android生成keystore是报错拒绝访问
  7. 使用Android(安卓)Studio创建Android(安卓)Wear项目
  8. Android(安卓)bootanimation 制作过程
  9. Android(安卓)通过按键旋转屏幕

随机推荐

  1. Android(安卓)人脸识别了解一下 (上)
  2. SQLite在Android中的使用
  3. Android(安卓)L开发指南
  4. Android(安卓)如何将定制的Launcher成为
  5. Android崩溃日志收集是个什么鬼?
  6. 一些Activity小技巧
  7. Android(安卓)signed APK程序正式签名方
  8. Android(安卓)入个门
  9. android之handler使用
  10. J2me游戏如何快速移植到Android(1)