拓展问题:
    1.在Looper的loop方法是死循环,为什么不会引起主线程卡死?

    1. for (; ;) {
    2. Message msg = queue.next(); // might block
    3. if (msg == null) {
    4. // No message indicates that the message queue is quitting.
    5. return;
    6. }
    7. // This must be in a local variable, in case a UI event sets the logge
    8. final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
    9. final long traceTag = me.mTraceTag;
    10. if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
    11. Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
    12. }
    13. final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
    14. final long end;
    15. try {
    16. msg.target.dispatchMessage(msg);
    17. end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
    18. } finally {
    19. if (traceTag != 0) {
    20. Trace.traceEnd(traceTag);
    21. }
    22. }
    23. msg.recycleUnchecked();
    24. }

    概循环里有阻塞,所以死循环并不会一直执行,相反的,大部分时间是没有消息的,所以主线程大多数时候都是处于休眠状态,也就不会消耗太多的CPU资源导致卡死。
    Message msg = queue.next(); // might block if(msg == null) {
    // No message indicates that the message queue is quitting.
    return;
    1.阻塞的原理是使用Linux的管道机制实现的
    2.主线程没有消息处理时阻塞在管道的读端

    3.binder线程会往主线程消息队列里添加消息,然后往管道写端写一个字节,这样就能唤醒主线程从管道读端返回,也就是说looper循环里queue.next()会调用返回…。在ActivityThread会创建一个H类,继承自Handler。ActivityThread 通过 ApplicationThread 和 AMS 进行进程间通讯,AMS 以进程间通信的方式完成 ActivityThread 的请求后会回调 ApplicationThread 中的 Binder 方法,然后 ApplicationThread 会向 H 发送消息,H 收到消息后会将 ApplicationThread 中的逻辑切换到 ActivityThread 中去执行,即切换到主线程中去执行,这个过程就是主线程的消息循环模型。比如发送 H.LAUNCH_ACTIVITY 消息,最终就是通知主线程调用Activity.onCreate() 。

    4.Looper: 每个线程只有一个Looper,负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消 息分给对应的Handler处理。
     MessageQueue:由Looper负责管理,采用先进先出的方式管理Message(消息队列)。
     Handler:把消息发送给Looper管理的MessageQueue并负责处理Looper分给它的消息。
      消息只能在某个具体的Looper上消耗,因此每个Handler都会绑定一个Looper。但是多个Handler可以绑定同一个Looper(这也是在主线程中能够创建新的Handler的原因)。

    为什么在Activity的onCreate使用以下代码可以刷新UI

    1. protected void onCreate(Bundle savedInstanceState) {
    2. super.onCreate(savedInstanceState);
    3. setContentView(R.layout.activity_main);
    4. tvTest=findViewById(R.id.tvTest);
    5. new Handler().post(new Runnable() {
    6. @Override
    7. public void run() {
    8. Log.e("TAG","thread 1 : "+Thread.currentThread());
    9. tvTest.setText("111111");
    10. }
    11. })
    12. Log.e("TAG","333333333");
    13. }

    【先打印出3333333333,再打印出“thread 1:……”】

    Activity的生命周期方法都是在UI线程中执行的,一个线程对应一个Looper,此处的Handler默认拿到的主线程的Looper,post方法会将其runnable放到消息队列中等待执行,而这之前,onCreate已经在处理,所以会当onCreate中的方法执行完了,Looper再取出一条来处理,即会取出handler它post的runnable。

    因此在使用handelr的post方法在做一些操作时,要注意其后面的代码,可能比它执行得还要快。