Handler处理机制简要解读

本文深入解析Android中的Handler机制,详细介绍了Handler、Looper、MessageQueue的工作原理及其交互过程,并通过源码层面阐述了消息的发送与处理流程。

最近在看《深入理解Android内核设计思想》,看完handler messageQueue Looper部分之后,做个记录。
以下包括参照源码做的整理和一些个人理解。

Handler做两件事:
(1)将消息压入消息队列。
(2)处理消息。
压入消息有两种方法: send(往消息队列压入各种Message对象)和post(将各类消息封装成Message对象然后压入消息队列)。

Handler类:
Looper mLooper;
MessageQueue messageQueue;
CallBack mCallBack;

Looper类:
MessageQueue messageQueue;
Thread thread;

MessageQueue类:一些入队列,出队列的方法。

Message类:
int what,arg1,arg2;
Handler target;//?
Object object;
public Message obtain();
public void recycle();
public void setTarget;

1.以下是平时写的handler处理消息的逻辑,加深理解之后:

     private Handler handler = new Handler() {
      /**
         * ------------------>Handler类
         * 构造方法中实现了如下内容:
         *    mLooper = Looper.myLooper();//获取当前线程(UI线程)的Looper对象(如此便将子线程和UI线程联系起来)
         *    mQueue = mLooper.mQueue;
         *    mCallback = callback;
         * 
         *     --------------->Looper类
         *     static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();//Looper类会提供一个静态变量。
         *       Looper myLooper() {
         *         return sThreadLocal.get();
         *       }
         * 
         *         -------------->ThreadLocal类
         *       public T get() {
         *          Thread t = Thread.currentThread();//
         *          ThreadLocalMap map = getMap(t);
         *       }
         */
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };


    public void HandleEvents() {
        new Thread(new Runnable() {
            @Override
            public void run() {
               //Android系统提供了一个全局的Message池,只需要获取就行了。
                Message msg = Message.obtain();
                msg.arg1 = 0;
                handler.sendMessage(msg);
            }
        }).start();
    }

2.关于activity如何处理各种事件:
在Activity类中有一个变量:ActivityThread mMainThread;

ActivityThread类:

//在ActivityThread类中相关对象和方法

final Looper mLooper = Looper.myLooper();
final H mH = new H();

 public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();//参考Looper类中的该方法,

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
        //主线程的Handler对象是获取的,普通线程的Handler是自己创建的。
            sMainThreadHandler = thread.getHandler();
        }

        ...
        Looper.loop();//开启消息循环

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

//获取主线程的handler对象
    final Handler getHandler() {
        return mH;
    }

 //内部类H继承了Handler,个人理解是对各类Message处理方法的封装
 private class H extends Handler {
 ...
 }
 //Looper类中相关方法
 //主线程调用该方法实例化主线程的Looper对象
 public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();//赋值给主线程的Looper对象sMainLooper
        }
    }
    //普通线程调用该方法实例化当前线程的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));
    }
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
 private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

  public static void loop() {
        final Looper me = myLooper();

        final MessageQueue queue = me.mQueue;
        for (;;) {
            Message msg = queue.next(); // might block
            ...
            try {
                msg.target.dispatchMessage(msg);//Handler开始分发消息,然后再处理(在Handler类中可找到该方法)
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            ...
            msg.recycleUnchecked();
        }
    }
//Handler类中相关方法
    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

总结:
Handler不直接处理消息,而是先将消息压入队列,等消息分发到自己这了再处理。这样做更好的协调了事件的处理,当你在做事件A的时候,突然又另外一个事件B要你处理,当B的优先级不高的情况下,按照Handler的消息处理方式,就是将事件B先暂时记下,当做完事件A之后再去处理事件B。
loop()函数的主要工作就是不断地从消息队列中取出需要处理的事件,然后分发给相应的责任人Handler。如果消息队列为空,则它很有可能进入睡眠或让出CPU。在其他事件的处理过程中,程序会post新的事件到队列中。APK应用程序就是不断的执行“处理队列事件”的工作,直到它退出运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值