Handler源码分析

一. android studio中使用

1.创建消息

1>通过Message类的obtain获取

Message message = Message.obtain(); //不含参数
Message message = Message.obtain(h);  //传进handler
 Message message = Message.obtain(h,callback);  //传进handler,callback
Message message = Message.obtain(h,what); //传进handle,what

2>通过Handler类的obtainMessage获取,实际也是调用Message中的obtain方法,区别在于此时的handler为它本身

Message msg=handler.obtainMessage();
Message msg=handler.obtainMessage(what);//传进what

3>设置Message参数

message.what=10; //消息类型
Bundle bundle =new Bundle();
bundle.putString("name","jack");
message.setData(bundle);//传进数据
message.setTarget(mHandlerT);//设置处理消息的目标handler

2.发送消息

调用Handler类中的sendMessage发送

mHandler.sendMessage(message); //立即发送
mHandler.sendMessageDelayed(message,1000); //延迟1s发送
mHandler.dispatchMessage(message);//分发消息,由传进的callback处理

3.处理消息

在继承Handler的类中重写handleMessage方法

public void handleMessage(Message msg) {
            Log.d(TAG,"receive message "+msg);
            tv.setText(msg.getData().getString("name"));
            switch (msg.what){  //一般通过msg.what来判断处理什么消息
                case 1:break;
                case 2: break;
            }
        }

二.源码分析

代码路径:framework/base/core/java/android/os/

1>创建消息

/获取Message对象
public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {  //相当于单向链表,sPool指向表头元素,每次取出表头元素
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
//回收Message对象
void recycleUnchecked() { 由recycle调用
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) { //最大容量为50
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
//Message中的参数
public int what  //一般用于指代消息类型
public int arg1;
public int arg2;  //参数一,参数二一般不怎么使用,而是使用setData(Bundle)传进数据
Handler target;//处理消息的Handler,可通过setTarget设置

2>发送消息

最终均会调用到sendMessageAtTime

public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0); //延迟为0
    }
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//当前时间加延迟时间
    }
public boolean sendMessageAtTime(@NonNull 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);
    }
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        msg.target = this;  //target设为本身,即Handler对象
        msg.workSourceUid = ThreadLocalWorkSource.getUid();
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);//MessageQueue
    }

查看MessageQueue中的enqueueMessage,主要逻辑如下

boolean enqueueMessage(Message msg, long when) {
    。。。
         msg.markInUse();
            msg.when = when;
            Message p = mMessages; //报存的头结点
            if (p == null || when == 0 || when < p.when) {  //异常情况
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) { //找到最后一个元素
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg; //尾插法,每次尾部插入一个msg
            }
 
            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
}

3>消息怎么传递到Handler的

在handleMessage中添加堆栈打印,打印如下
在这里插入图片描述
在主线程中通过Looper.loop来处理消息

public static void loop() {
       。。。
        for (;;) {
            Message msg = queue.next(); // might block ,重点关注,取出MessageQueue中的消息
         msg.target.dispatchMessage(msg); //分发消息
            msg.recycleUnchecked();
        }
    }
 public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);//处理消息
        }
    }

HandlerThread.run

public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

MessageQueue中的next

Message next() {
        。。。
       int pendingIdleHandlerCount = -1; // -1 only during first iteration
       int nextPollTimeoutMillis = 0;
       for (;;) {          
           synchronized (this) {
               // Try to retrieve the next message.  Return if found.
               final long now = SystemClock.uptimeMillis();
               Message prevMsg = null;
               Message msg = mMessages;
               if (msg != null && msg.target == null) {
                   // Stalled by a barrier.  Find the next asynchronous message in the queue.
                   do {
                       prevMsg = msg;
                       msg = msg.next;
                   } while (msg != null && !msg.isAsynchronous());
               }
               if (msg != null) {
                   if (now < msg.when) {
                       // Next message is not ready.  Set a timeout to wake up when it is ready.
                       nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                   } else {
                       // Got a message.
                       mBlocked = false;
                       if (prevMsg != null) {
                           prevMsg.next = msg.next;
                       } else {
                           mMessages = msg.next;
                       }
                       msg.next = null;
                       if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                       msg.markInUse();
                       return msg;
                   }
               } else {
                   // No more messages.
                   nextPollTimeoutMillis = -1;
               }
           if (mQuitting) {
                   dispose();
                   return null;
               }
   }

三.Registrant和RegistrantList

常见于rilj中

比如UiccController中处理EVENT_ICC_STATUS_CHANGED,其获取消息为以下代码

mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, i);
public void registerForIccStatusChanged(Handler h, int what, Object obj) {
          Registrant r = new Registrant (h, what, obj);
          mIccStatusChangedRegistrants.add(r); //mIccStatusChangedRegistrants为 RegistrantList对象
     }
//RegistrantList中的add
add(Registrant r)
      {
          removeCleared();
          registrants.add(r);//registrants为ArrayList对象
      }

发送消息时调用RegistrantList中的 notifyRegistrants

notifyRegistrants()
    {
        internalNotifyRegistrants(null, null);
    }
 internalNotifyRegistrants (Object result, Throwable exception)
    {
       for (int i = 0, s = registrants.size(); i < s ; i++) {
            Registrant  r = (Registrant) registrants.get(i);
            r.internalNotifyRegistrant(result, exception);
       }
    }
//Registrant
 internalNotifyRegistrant (Object result, Throwable exception)
    {
        Handler h = getHandler();
        if (h == null) {
            clear();
        } else {
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = new AsyncResult(userObj, result, exception);
            h.sendMessage(msg);//调用Handler中的sendMessage 发送消息
        }
    }

后续逻辑与第二部分相同

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值