Handler、Looper、Message随笔

来源:互联网 发布:知乎 刘备 王者 编辑:程序博客网 时间:2024/05/29 09:58

在子线程中实现Handler的大致操作:

    mThread = new Thread() {            @Override            public void run() {                Looper.prepare();//Looper.prepare()是在后台轮询线程中调用的                // Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,                // 需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,                // 从消息队列里取消息,处理消息。                // 定义Handler的逻辑,Handler在哪个线程初始化就属于哪个线程                mThreadHandler = new Handler() {                    @Override                    public void handleMessage(Message msg) {                        //TODO                    }                };                ...                Looper.loop();            }        };        mThread.start();

等到mThreadHandler 初始化之后,就可以在其他地方使用mThreadHandler 发送Message了。

具体的使用可以参考:Android-仿微信图片选择器中ImageLoader类的实现


Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

摘录:

Looper主要作用:1、  与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。2loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。

Handler部分源码

public Handler() {          this(null, false);  }  public Handler(Callback callback, boolean async) {          if (FIND_POTENTIAL_LEAKS) {              final Class<? extends Handler> klass = getClass();              if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&                      (klass.getModifiers() & Modifier.STATIC) == 0) {                  Log.w(TAG, "The following Handler class should be static or leaks might occur: " +                      klass.getCanonicalName());              }          }          mLooper = Looper.myLooper();          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如何与如何与MessageQueue联系上的:14行:通过Looper.myLooper()获取了当前线程保存的Looper实例,然后在19行又获取了这个Looper实例中保存的MessageQueue(消息队列),这样就保证了handler的实例与我们Looper实例中MessageQueue关联上了。
总结:1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。2、Looper.loop()会让当前线程进入一个无限循环,不断从MessageQueue的实例中读取消息(通过queue.next()),然后回调msg.target.dispatchMessage(msg)方法。3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue相关联。4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

图解
这里写图片描述


Android 进阶14:源码解读 Android 消息机制( Message MessageQueue Handler Looper)
相比于鸿扬的博客,讲得比较详细


Android 中Message,MessageQueue,Looper,Handler详解+实例
有结合实例在子线程中创建Handler