Handler消息机制

作者: 明朗__ | 来源:发表于2017-04-01 22:40 被阅读94次

    在Android中 整个系统的“消息机制” “事件传递” “反馈机制”就是由Handler来进行统一管理的


    作用:
    为了避免ANR,我们会通常把 耗时操作放在子线程里面去执行,因为子线程不能更新UI,所以当子线程需要更新的UI的时候就需要借助到安卓的消息机制,也就是Handler机制了。

    1. 我们先从Android的启动类AcitvityThread的main函数看起


    2. 我们继续深入 Looper.loop();


      msg.recycleUnchecked();//这里消息处理完成后 就进行回收
      
    3. 进入msg.target.dispatchMessage(msg);看看Handler是怎么处理消息的
    public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    
    - 如果msg.callback != null 那么这个callback代表什么呢
    
    public final class Message implements Parcelable {
    Runnable callback;//callback代表着一个Runnable
    }
    //在看看Handler的 handleCallback(msg);就明白
    private static void handleCallback(Message message) {
            message.callback.run();//这里的run()就是一个回调 千万别认为在分线程中执行
        }
    
    - 根据以上分析一目了然 我们平时这样写的代码:
    
    //写法一
    new Handler().post(new Runnable() {
                @Override
                public void run() {//在Hnadler在主线程的时候 run()也在主线程中执行
                    //这里就不用Handler去处理 而是你自己在run()回调里面处理
                }
            });
    //写法二
    Runnable runnable=new Runnable() {
                @Override
                public void run() {
                    //xxxxxx
                }
            };
     new Handler().postDelayed(runnable,1000);
    
    1. 分析完handleCallback(msg); 再接着往下走:
    public void dispatchMessage(Message msg) {
         if (msg.callback != null) {
             handleCallback(msg);
         } else {
             if (mCallback != null) {//mCallback是Handler中定义的一个回调接口
                 if (mCallback.handleMessage(msg)) {//执行回调方法
                     return;
                 }
             }
             handleMessage(msg);//若以上都为空 则执行Handler的handleMessage()方法
         }
     }
    
    - Handler.Callback
    
    public class Handler {
             final Callback mCallback;//接口
             public interface Callback {
             public boolean handleMessage(Message msg);
             }
             public void handleMessage(Message msg) { }
    }
    
    - 平时代码写法:
    
    private Handler handler=new Handler(new Handler.Callback() {
            //这里就给Handler的Callback赋值并回调
            @Override
            public boolean handleMessage(Message msg) {
                return false;
            }
        });
    
    1. 以上是分析了Handler怎么处理消息 再看Handler是如何发生消息的


    public final boolean postAtTime(Runnable r, long uptimeMillis) {
            return sendMessageAtTime(getPostMessage(r), uptimeMillis);
        }
    public final boolean post(Runnable r){
           return  sendMessageDelayed(getPostMessage(r), 0);
        }
    //直接发送消息
    public final boolean sendMessage(Message msg){
            return sendMessageDelayed(msg, 0);
        }
    //发送空消息
    public final boolean sendEmptyMessage(int what) {
            return sendEmptyMessageDelayed(what, 0);
        }
    //发送延迟消息
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
            Message msg = Message.obtain();
            msg.what = what;
            return sendMessageDelayed(msg, delayMillis);
        }
    //在某一时间点发送消息
    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;
            }
          //这里将消息插入MessageQueue队列中
            return enqueueMessage(queue, msg, uptimeMillis);
        }
    

    由上得出 Handler不管是以哪种方式发送消息 最后都由sendMessageAtTime(msg, delayMillis)该方法来处理
    --曾经面试在这里躺坑了--

    1. 最后一些建议:
      • 创建Message对象的时候这样创建:
    Message message=Message.obtain();
    //源码:
    /**
         * Return a new Message instance from the global pool. Allows us to
         * avoid allocating new objects in many cases.
         */
    public static Message obtain() {
            synchronized (sPoolSync) {
                if (sPool != null) {
                    Message m = sPool;
                    sPool = m.next;
                    m.next = null;
                    m.flags = 0; // clear in-use flag
                    sPoolSize--;
                    return m;
                }
            }
            return new Message();
        }
    //通过注释我们就知道这样创建的Message是从消息池里面获取的 避免重复创建对象;
    
    1. 分析了发送消息和处理消息 最后看看系统Handler做了哪些工作
    public final class ActivityThread {
            final H mH = new H();
            private class H extends Handler {
             public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                switch (msg.what) {
                    case LAUNCH_ACTIVITY: {//Activity---onStart()
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        } break;
                    case RELAUNCH_ACTIVITY: {//Activity--onRestart
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                        ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                        handleRelaunchActivity(r);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                         } break;
                    case PAUSE_ACTIVITY://Activity--onPause
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                                (msg.arg1&2) != 0);
                        maybeSnapshot();
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                        ..........................................//后面的代码执行观看
            }
    }
    

    通过以上源码发现Android四大组件的生命周期全部都是由Handler进行统一管理的 由此看出Handler在Android中的重要性。

    **针对Looper是如何创建的 以及MessageQueue对Message的入队和出队是如何操作的 就放在下一篇文章讲解 **

    相关文章

      网友评论

        本文标题:Handler消息机制

        本文链接:https://www.haomeiwen.com/subject/mhoiottx.html