zoukankan      html  css  js  c++  java
  • HandlerThread: HandlerThread的理解

    Android为了方便对Thread和Handler进行封装,也就是HandlerThread。HandlerThread继承自Thread,说白了就是Thread加上一个Looper。源码:

    可以看到其本身便持有一个Looper对象。

    之前学习的时候有两个疑问:

    1. HandlerThread为什么start完了之后不会退出?

    一般我们都是在某个方法里(如onCreate)调用start方法来启动HandlerThread:

    mWorkThread = new HandlerThread("workThread");
    mWorkThread.start();

    那岂不是在调用完start方法之后就退出了?那这有什么意义,如果是一个普通的线程:

    Thread thread = new Thread();
    thread.start();

    在调用完start()方法之后肯定会退出的。

    查看HandlerThread源码:

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

    当调用完start()方法后系统会自动调用run()方法,run方法里有一个 Looper.loop(); 

    可以看到这个looper方法里有一个死循环,它也是跑在run方法里的,所以HandlerThread在start()完了之后不会立即退出。

    2. Handler里的handlerMessage()方法究竟运行于哪个线程?

    handlerMessage()方法究竟运行于哪个线程,得看这个方法在哪个线程里被调用,之前分析过handlerMessage是在Looper的loop()方法里辗转被调用的。

    Looper#loop()

     Handler#dispatchMessage()

    那其实可以这样说,Looper.loop()方法跑在哪个线程,handlerMessage就跑在哪个线程。

    对于自定义的Thread+Looper方式:

      class LooperThread extends Thread {
          public Handler mHandler;
    
          public void run() {
              Looper.prepare();
    
              mHandler = new Handler() {
                  public void handleMessage(Message msg) {
                      // process incoming messages here
                  }
              };
    
              Looper.loop();
          }
      }

    很明显,handlerMessage()方法跑在子线程。

    对于HandlerThread方式:

    HandlerThread#run()

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

    也是跑在子线程。

    对于mHandler = new Handler()方式:

    虽然未传Looper, 但默认使用的是主线程的Looper, 所以此时handlerMessage跑在主线程。

  • 相关阅读:
    输入流输出流
    WIN32_FIND_DATA
    typeid
    为什么要内存对齐 Data alignment: Straighten up and fly right
    fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h
    memcmp
    DPI
    英寸、 Picas、 点、 跨度和 Twips 之间的关系
    如何解决 “fatal error C1083: ”无法打开包括文件
    hdoj 1269迷宫城堡解题报告
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/11571166.html
Copyright © 2011-2022 走看看