个人对于Handler的理解,用于记录和帮助理解。

Android的消息队列机制中具有三个重要元素,Handler、Looper、MessageQueue。

  1. Looper中循环取消息并发送消息
  2. MessageQueue则用来存储消息
  3. Handler则用来创建消息

Handler

Handler在android用于通信,个人接触到的普遍作用是用于更新UI。因为多线程可能会导出界面更新出错。,所以Android不允许在子线程中进行UI的更新,并给与Hnadler的通信方式。
基本用法很简单

//接收消息Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        text.setText("hello world");    }};//发送消息//发送延时消息mHandler.sendEmptyMessageDelayed(0,0);//发送消息的三种方式mHandler.sendEmptyMessage(0);mHandler.sendMessage(mHandler.obtainMessage());mHandler.post(new Runnable() {    @Override    public void run() {    }});

对于以上三种方式,实现方式一致,只是外在接口形式不同。源码如下:

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {    MessageQueue queue = mQueue;    if (queue == null) {        RuntimeException e = new RuntimeException(                this + " sendMessageAtTime() called with no mQueue");        Log.w("Looper", e.getMessage(), e);        return false;    }    return enqueueMessage(queue, msg, uptimeMillis);}

最后都会执行这个方法,所以结合实际情况调用即可。
enqueueMessage方法则消息依次加入MessageQuene中。
post有所不同,内部会加载方法getPostMessage(r)

public final boolean post(Runnable r){   return  sendMessageDelayed(getPostMessage(r), 0);}

getPostMessage方法内部将r赋值给msg的callback

private static Message getPostMessage(Runnable r) {    Message m = Message.obtain();    m.callback = r;    return m;}

在Handler的构造函数中,初始化变量Looper、MessageQueue。此步骤关联Looper、MessageQueue。

public Handler(Callback callback, boolean async) {    ...    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;}

Lopper

在myLooper中,拿到Looper

public static @Nullable Looper myLooper() {    return sThreadLocal.get();}

Looper不能通过new创建,只能通过peprepare方式创建。

private static void prepare(boolean quitAllowed) {    //通过此判断保证一个线程中只有一个Looper    if (sThreadLocal.get() != null) {        throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper(quitAllowed));}

Looper构造函数

private Looper(boolean quitAllowed) {    //因为Looper一个线程只能具有一个,所以一个线程中也只会有一个MessageQueue,并将Looper与当前线程绑定    mQueue = new MessageQueue(quitAllowed);    mThread = Thread.currentThread();}

Looper的loop方法用来循环消息队列,取出消息并进行发送

public static void loop() {    //拿到Looper    final Looper me = myLooper();    if (me == null) {        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");    }    final MessageQueue queue = me.mQueue;    ...    for (;;) {        //取出消息        Message msg = queue.next(); // might block        ...        //发送消息        msg.target.dispatchMessage(msg);        ...    }}

通过死循环不停的拿到消息并发送消息。

Message

随后我们进入Message方法中,查找target,发现方法

public static Message obtain(Handler h) {    Message m = obtain();    m.target = h;    return m;}

在Handler最终发送消息的方法中,发现同样代码

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {    //target指向Handler自己    msg.target = this;    if (mAsynchronous) {        msg.setAsynchronous(true);    }    return queue.enqueueMessage(msg, uptimeMillis);}

在我们可以通过obtain获取一个复用Message,在此方法中,将target指向了Handler,所以最终会调用Handler的dispatchMessage方法,接着查看Handler的dispatchMessage方法

//我们经常重写的方法public void handleMessage(Message msg) {}/*** Handle system messages here.*/public void dispatchMessage(Message msg) {    //检查callback,即post发送消息时赋值的callback    if (msg.callback != null) {        handleCallback(msg);    } else {        //执行过滤器方法,在构造函数中进行初始化        if (mCallback != null) {            if (mCallback.handleMessage(msg)) {                return;            }        }        //在此调用重写的方法        handleMessage(msg);    }}//post发送请求方式private static void handleCallback(Message message) {    message.callback.run();}

以上,消息发送完全完毕。

为什么Activity中不需要我们进行Looper的创建呢?
因为ActivityThread的main方法中帮助我们进行了Looper的创建。因为Looper的创建过程中绑定了当前线程(主线程),所以Handler可以在UI线程中更新UI数据。

更多相关文章

  1. Android(安卓)数据存储和文件使用案例分析
  2. ExifInterface使用,Android(安卓)2.0新增类
  3. android 使用AsyncTask实现异步下载文件
  4. android通过更改hosts免优酷广告方法
  5. 如何优雅的避免android(安卓)运行时崩溃
  6. android 热修复之类加载机制
  7. Android中Intent概述及使用
  8. android 跨应用启动/绑定Service && aidl
  9. Android进阶(一)View体系

随机推荐

  1. Android公共库(缓存,下拉ListView,下载管
  2. android报表例子
  3. android 热更新(无框架)
  4. android中的selector背景选择器的用法
  5. Android应用开发——TextView控件属性列
  6. Android系统分析之Activity的启动流程
  7. android通过adb设置以太网共享
  8. Android调用shell脚本并获得输出
  9. Android(安卓)Studio项目创建和模拟器配
  10. 学了一年的Android,还不会调试?你白学了!