红橙Darren视频笔记 Handler源码简析与handler框架模拟 ThreadLocal

1.handler的使用

public class MainActivity extends AppCompatActivity {

    MyHandler myHandler;
    private static final int MSG_INDEX_1 = 1;
    private static final int MSG_INDEX_2 = 2;
    private static final int MSG_INDEX_3 = 3;
    private TextView tv1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv1 = findViewById(R.id.tv1);
        Message message = new Message();
        myHandler = new MyHandler(this);
        message.what = MSG_INDEX_1;
        myHandler.sendMessageDelayed(message,100);
        myHandler.sendEmptyMessageDelayed(MSG_INDEX_2, 10000);
        myHandler.sendEmptyMessageDelayed(MSG_INDEX_3, 5000);
    }

    static class MyHandler extends Handler {
        WeakReference<MainActivity> mWeakReference;

        public MyHandler(MainActivity activity) {
            mWeakReference = new WeakReference(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_INDEX_1:
                    Toast.makeText(mWeakReference.get(), "1111", Toast.LENGTH_SHORT).show();
                    break;
                case MSG_INDEX_2:
                    Toast.makeText(mWeakReference.get(), "2222", Toast.LENGTH_SHORT).show();
                    break;
                case MSG_INDEX_3:
                    Toast.makeText(mWeakReference.get(), "3333", Toast.LENGTH_SHORT).show();
                    break;
                default:
            }
        }
    }
}

	// 其中有我们容易忽略的handler的创建部分 以下为handler的构造方法
    public Handler(@Nullable 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());
            }
        }
        // 注意点1 之后用到
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        // 注意点2 之后用到
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

2.sendMessage

sendMessage有好几种方式,其最终调用的都是public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis)

我们以sendMessageDelayed为例开始分析

    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与Message结合一起组成了一个队列结构
        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;
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        // 消息 入队列
        return queue.enqueueMessage(msg, uptimeMillis);
    }

    boolean enqueueMessage(Message msg, long when) {
        ...

        synchronized (this) {
            ...
            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            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;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

我们需要着重分析入队的方法 以下面代码为例 分析Message与MessageQueue为什么构成了一个队列 是如何入队列的

        myHandler = new MyHandler(this);
        Message message = new Message();
        message.what = MSG_INDEX_1;
        myHandler.sendMessageDelayed(message,100);
        myHandler.sendEmptyMessageDelayed(MSG_INDEX_2, 10000);
        myHandler.sendEmptyMessageDelayed(MSG_INDEX_3, 5000);

其他逻辑不难理解 主要分析enqueueMessage内部逻辑

	boolean enqueueMessage(Message msg, long when) {
        ...

        synchronized (this) {
            ...
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            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;
            }
			...
        }
        return true;
    }

这个入队的逻辑 简单来说是按照执行时刻入队 越先执行的msg 越先入队 比如我的代码执行入队操作后的结构类似下面这样

3.handleMessge

那么handleMessge是在哪里触发的呢 

实际上我们忽略了Handler是在Activity主线程执行的  在ActivityThread的main函数 有两句重要的执行

Looper.prepareMainLooper以及Looper.loop

    public static void main(String[] args) {
        ...
        // 初始化主线程的Looper
        Looper.prepareMainLooper();

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

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        
        Looper.loop();
    }

    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }


    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static void prepare(boolean quitAllowed) {
        // sThreadLocal 中存储了ThreadLocalMap 该map以当前线程为key looper为value 确保一个线程只有一个looper
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        // 一个线程只创建一次looper
        sThreadLocal.set(new Looper(quitAllowed));
    }

至于Looper.loop则是开启死循环 遍历MessageQueue中的Message 让handler执行handleMessage

4.Looper.loop方法

    public static void loop() {
        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
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            ...
            try {
                // msg.target 是handler 即执行handler的dispatchMessage方法
                msg.target.dispatchMessage(msg);
                if (observer != null) {
                    observer.messageDispatched(token, msg);
                }
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } catch (Exception exception) {
                if (observer != null) {
                    observer.dispatchingThrewException(token, msg, exception);
                }
                throw exception;
            } finally {
                ThreadLocalWorkSource.restore(origWorkSource);
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            ..
			// 回收消息
            msg.recycleUnchecked();
        }
    }

	// Handler.java
    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

5.handler的整体工作流程

1.looper.prepare

主要负责创建Looper对象 looper对象每个线程只有一个 保存在Looper的静态变量ThreadLocal<Looper>  sThreadLocal中

ThreadLocal保存形式为保存在ThreadLocalMap 是一个Map key为当前线程 value为looper

保证一个线程只有一个looper

2.创建handler

创建handler时 就将handler关联到相关线程的looper和messageQueue 形成 Handler- thread-looper-queue的对应关系

其中有个异常 如果没有在创建Handler之前调用looper.prepare(创建looper) 抛出以下异常

            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");

3.sendMessage

该方法主要是构建消息队列 按照消息的执行时间将Message形成队列 该队列会保存在Looper中

4.looper.loop

该方法主要是从消息队列取出对头元素 交由handler执行,之后会触发Handler的handleMessage方法 

6.handler框架模拟

本节所有文件都是自己新建的,目的是模拟ActivityThread中handler,looper等相关类的生命周期 与Android原生的文件同名文件没有关系

1.Message

public class Message {
    // 何时执行Message
    public long when;
    // 用于区分各个Message
    public int what;
    // 标记当前Message由哪个handler处理
    public Handler target;
    // 链表结构 指向下一个Message
    Message next;
    // 用于通过Message传递信息给Handler
    public Object obj;
}

2.MessageQueue

public class MessageQueue {// 不是严格意义的队列 入队列按照when入队列 出队则是和队列的规则一致
    // 虽然只有一个Message 然而Message.next 指向下一个Message 依次类推 知道某一个Message的next指向null 其实组成一个队列
    Message mMessages;

    // 按照when的value 从小到大入队列
    boolean enqueueMessage(Message msg, long when) {
        System.out.println("enqueueMessage msg.what " +msg.what);
        synchronized (this) {
            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;
            } 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.
                Message prev;
                for (; ; ) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }
        }
        return true;
    }

    // 从队列头部出队列
    Message next() {
        for (; ; ) {
            synchronized (this) {
                // Try to retrieve the next message.  Return if found.
                final long now = System.currentTimeMillis();
                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);
                }
                if (msg != null) {
                    if (now < msg.when) {
                        // Next message is not ready.  Set a timeout to wake up when it is ready.
                    } else {
                        // Got a message.
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        return msg;
                    }
                } else {
                    // No more messages.
                }
            }
        }
    }
}

3.Handler

public class Handler {
    MessageQueue mQueue;

    public Handler() {
        Looper looper = Looper.myLooper();
        if(looper == null){// 创建Handler之前必须调用Looper.prepare
            // 即创建Handler之前 必须能根据当前线程取出当前线程的Looper 否则报错
            throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
        }
        // 将一一对应的Looper-Queue中的Queue赋值给当前handler中的Queue
        // 最终形成 Handler-Looper-Thread 的相互对应的关系
        //          |       |
        //          Q u e u e
        mQueue= looper.mQueue;
    }

    // 发送消息 本质是入队列
    public void sendMessage(Message message) {
        sendMessageDelayed(message,0);
    }

    // 发送消息 本质是入队列
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, System.currentTimeMillis() + delayMillis);
    }

    // 发送消息 本质是入队列
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

    public void handleMessage(Message msg) {
    }

    // 发送消息 本质是入队列
    private boolean enqueueMessage(MessageQueue queue, Message msg,
                                   long uptimeMillis) {
        // 确认Message交由本handler处理
    	msg.target = this;
        return queue.enqueueMessage(msg, uptimeMillis);
    }


}

4.Looper

public class Looper {
    // Looper内部只有一个Looper实例 存储在sThreadLocal
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();
    public MessageQueue mQueue;

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

    public Looper() {
        // 一个looper匹配唯一一个队列mQueue
        mQueue = new MessageQueue();
    }

    public static void prepare() {
        if (sThreadLocal.get() != null) {
            // 确保一个Looper只返回唯一一个Looper实例
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        // 在sThreadLocal中存储Looper实例 键值对为 thread-looper
        sThreadLocal.set(new Looper());
    }
    /*
     *    ThreadLocal的set方法
     *     public void set(T value) {
     *         // 获取当前thread
     *         Thread t = Thread.currentThread();
     *         // 以当前thread为key Looper为value 存储在ThreadLocalMap
     *         // 即 ThreadLocalMap 存储了唯一的键值对 thread-looper
     *         // 一个thread只有一个looper 且必须有一个(否则loop时报错)
     *         ThreadLocalMap map = getMap(t);
     *         if (map != null)
     *             map.set(this, value);
     *         else
     *             createMap(t, value);
     *     }
     */

    /**
     * Run the message queue in this thread. Be sure to call
     * {link #quit()} to end the loop.
     */
    public static void loop() {
        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
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            try {
                // 由调用sendMessage的handler调用handleMessage
                msg.target.handleMessage(msg);
            } catch (Exception exception) {
                throw exception;
            }
            // 回收消息部分省略
            // msg.recycleUnchecked();
        }
    }
}

5.TextView

public class TextView {
    private Thread mThread;
    public TextView(){
        mThread = Thread.currentThread();
    }

    public void setText(CharSequence text){
        checkThread();
        System.out.println("update "+text);
    }

    void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new RuntimeException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }
}

6.Activity

public class Activity {
    public void onCreate(){
        System.out.println("onCreate execute");
    }

    public void onResume(){
        System.out.println("onResume execute");
    }

    public TextView findViewById(int tv) {
        return new TextView();
    }
}

7.MyActivity

public class MyActivity extends Activity{
    private TextView mTextView;

    private Handler mHandler = new Handler(){
        // 由于Handler在主线程创建 Handler构造方法Looper.myLooper时取得了主线程的Looper
        // handleMessage在主线程执行
        public void handleMessage(Message msg) {
            System.out.println("msg.what 必定=999 "+msg.what);
            mTextView.setText((String)msg.obj);
            System.out.println("handleMessage在主线程执行: "+Thread.currentThread());
        };
    };

    @Override
    public void onCreate() {
        super.onCreate();
        mTextView = findViewById(RR.id.text_view);
        new Thread(){
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // mTextView.setText("");
                // Only the original thread that created a view hierarchy can touch its views.
                // 子线程禁止直接操作UI

                // 如果想在子线程创建Handler 需要调用Looper.prepare 否则抛出异常
                // Can't create handler inside thread that has not called Looper.prepare()

                // Looper.prepare();
                // Handler my = new Handler();
                // Looper.loop();

                // 开启子线程
                System.out.println("child thread "+Thread.currentThread());
                Message message = new Message();
                message.obj = "update text";
                message.what = 999;
                // 向在主线程中创建的mHandler发送消息 消息入栈 之前在ActivityThread已经开启轮询Looper.loop();
                // 之后则会被mHandler handle这个message
                mHandler.sendMessage(message);
            };
        }.start();
    }

    @Override
    public void onResume() {
        super.onResume();
    }
}

8.RR(模拟R文件)

public class RR {
	public final static class id{
		public static final int text_view = 0x0011;
	}
}

9.ActivityThread

public class ActivityThread {
    final H mH = new H();
    public static final int RESUME_ACTIVITY         = 107;
    public static void main(String[] args) {
    	System.out.println("当前是主线程: "+Thread.currentThread());
        // 初始化当前Thread的looper
        Looper.prepare();
        ActivityThread thread = new ActivityThread();
        // 开始Activity的生命周期
        thread.attach(false);
        // 开启消息的轮询
        Looper.loop();
    }

    private void attach(boolean b) {
        Activity myActivity = new MyActivity();
        // onCreate执行
        myActivity.onCreate();
        Message message = new Message();
        // 将Activity传递进Message
        message.obj = myActivity;
        message.what = RESUME_ACTIVITY;
        // message在mH的队列中入队 在轮询之后 会由mH处理Message
        mH.sendMessage(message);
    }

    private class H extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == RESUME_ACTIVITY){// 处理attach中的message
                Activity mainActivity = (Activity) msg.obj;
                mainActivity.onResume();
            }
        }
    }

}

执行结果:

当前是主线程: Thread[main,5,main]
onCreate execute
enqueueMessage msg.what 107
onResume execute
child thread Thread[Thread-2,5,main]
enqueueMessage msg.what 999
msg.what 必定=999 999
update update text
handleMessage在主线程执行: Thread[main,5,main]

7.handler相关的常见面试题

1.MessageQueue 是什么结构?

MessageQueue 是队列的数据结构,以message为节点构成先入先出的队列

2.ThreadLocal 是怎么保证线程安全的

ThreadLocal 是线程隔离的 即使保存了一个static的ThreadLocal 实例 实际上使用的时候ThreadLocal 的get与set方法都还是根据当前线程来存取

观察ThreadLocal的set与get方法

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

可以知道ThreadLocal 之所以是线程隔离的 是因为每个Thread有自己的ThreadLocalMap,该map以当前线程为key 想要保存的值为value,这意味着ThreadLocal 会根据当前线程的不同,存取的值也在不同的线程的ThreadLocalMap中

借助

https://zhuanlan.zhihu.com/p/133433717 

的例子

public class Test {
	private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
		// 复写initialValue方法为ThreadLocal设置一个初始值,并获取调用了threadLocal的线程id
		@Override
		protected Integer initialValue() {
			System.out.println("current thread id:"
					+ Thread.currentThread().getId());
			System.out.println("threadLocal==>"+threadLocal);
			return 10;
		}
	};

	public static void main(String[] args) {
		// main方法就对应一个线程了,我们在主线程中对threadLocal的值进行修改
		System.out.println("mian thread");
		System.out.println("threadLocal in main thread:" + threadLocal.get());
		threadLocal.set(100); // 改变threadLocal的值
		System.out.println("threadLocal in main thread again:"
				+ threadLocal.get());

		System.out.println("start new thread");
		// 新创一个线程,并获取threadLocal的值
		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("threadLocal in new thread:"
						+ threadLocal.get());
			}
		});
		thread.start();
	}
}

乍一看 test使用了类变量threadLocal 应该所有线程使用同一个实例

然而输出如下

mian thread
current thread id:1
threadLocal==>Father.Test$1@15db9742
threadLocal in main thread:10
threadLocal in main thread again:100
start new thread
current thread id:11
threadLocal==>Father.Test$1@15db9742
threadLocal in new thread:10

这是因为虽然threadLocal 是同一个变量 但是观察上面ThreadLocal的set与get方法 可知 它存储在Map的key是当前的Thread,因此实际上不同的线程存储在不同的ThreadLocalMap中。

3.使用handler的常见错误

何时会引发java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

为什么在主进程中创建Handler没有这样的问题呢?

在子线程创建Handler并且不调用looper的prepare方法 

至于主进程中创建Handler没有这个问题,自然是主进程自己已经帮我们做了

	// ActivityThread.java
	public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        // 准备主进程的looper
        Looper.prepareMainLooper();

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

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        // 启动looper的循环
        // 跟踪这里 
        Looper.loop();

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


	// Looper.java
    public static void loop() {
        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;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        for (;;) {
            ...
            try {
                // 分配msg
                msg.target.dispatchMessage(msg);
                end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            ...
        }
    }


	// Handler.java
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            // 处理msg
            handleMessage(msg);
        }
    }

ActivityThread.java
    private class H extends Handler {
        public void handleMessage(Message msg) {
        	switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    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, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                case RELAUNCH_ACTIVITY: {
                    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:
                ...
        }
    
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值