HandlerThread,顾名思义,是将Thread与Handler结合的一种新型线程类。它本质上仍然是一个线程,但在内部嵌套了一个与之相关的Handler,从而实现了轻量级的异步处理。相较于普通线程,HandlerThread具有以下特点:

1. 普通线程类:HandlerThread的使用方法与普通线程类似。用户需要创建一个新的HandlerThread对象,并通过start()方法来启动该线程。

2. 内部嵌套了Handler:HandlerThread包含一个与其关联的Handler对象,这使得线程之间的数据交互变得更加简便。

3. 串行运行:为了实现任务的串行阻塞队列,HandlerThread内部采用了Looper机制。

下面我们来看一个简单的使用示例:

```java

// 2.1 作为线程使用

// 与普通线程相比,HandlerThread的优势在于可以在其中创建工作Handler对象。

// 在异步任务结束后,可以将消息发送到工作区的Handler的handleMessage方法中。

// 而普通的线程则需要手动维持Looper的prepare()和loop()方法。

public class MainActivity extends AppCompatActivity {

private static final int MY_HANDLER_ID = 1;

private Handler mMyHandler;

private Runnable mMyRunnable;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mMyHandler = new Handler(new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

switch (msg.what) {

case MY_HANDLER_ID:

// 处理消息

break;

}

return true;

}

});

mMyRunnable = new Runnable() {

@Override

public void run() {

// 执行异步任务

Message message = Message.obtain();

message.what = MY_HANDLER_ID;

mMyHandler.sendMessage(message);

}

};

HandlerThread myThread = new HandlerThread("MyThread");

myThread.start(); // 开启线程并关联工作Handler

mMyRunnable.run(); // 执行异步任务

}

}

```

```java

// 创建和执行MYHandlerThread类,添加线程名称

MYHandlerThread myHandlerThread = new MYHandlerThread("xiaohan");

myHandlerThread.start();

class MYHandlerThread extends HandlerThread {

public MYHandlerThread(String name) {

super(name);

}

// 重写onLooperPrepared()方法

@Override

protected void onLooperPrepared() {

super.onLooperPrepared();

// 执行耗时任务

SystemClock.sleep(3 * 1000);

}

// 任务结束,将结果发送至工作区的Handler中

private Handler subHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

String result = (String) msg.obj;

Log.i(TAG, "handleMessage: 子线程中的Handler " + result);

}

};

@Override

public void run() {

// 在run方法中执行耗时任务,并将结果发送至subHandler中进行处理

onLooperPrepared();

}

}

// 结束线程

mHandlerThread.quit();

```

以下是重构后的代码:

```java

// 1. 创建HandlerThread对象,填写线程名称,通过start()启动该线程

mHandlerThread = new HandlerThread("xiaohan");

mHandlerThread.start();

// 2. 创建WorkHandle工作区,处理不同的异步任务

mWorkHandler = new Handler(mHandlerThread.getLooper()) {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case UPDATE_THREAD1:

Log.i(TAG, "handleMessage: 子线程处理任务1");

break;

case UPDATE_THREAD2:

Log.i(TAG, "handleMessage: 子线程处理任务2");

break;

}

}

};

// 3. 发送消息到工作区处理

Message message = mWorkHandler.obtainMessage();

message.what = UPDATE_THREAD1;

message.obj = num + "";

mWorkHandler.sendMessage(message);

// 4. 结束线程

mHandlerThread.quit();

```

. 创建Handler并绑定Looper

要创建一个Handler并将其与当前线程的Looper对象绑定,可以使用getLooper()方法获取当前线程的Looper对象,然后在创建Handler时与其绑定。这样,该Handler将持有Looper以及MessageQueue,使其能够正常工作。

3.2 开启HandlerThread线程

要启动HandlerThread线程,可以调用其start()方法。这将开始执行线程的run()方法,如下所示:

```java

// 创建HandlerThread,添加线程名称

HandlerThread handlerThread = new HandlerThread("MyThread");

handlerThread.start(); // 开启线程

// 通过getLooper()获取当前线程的Looper对象,在创建Handler时与其绑定

Looper looper = handlerThread.getLooper();

Handler handler = new Handler(looper);

```

3. 发送异步任务

根据需要,可以将异步的Message信息发送到工作区的handleMessage方法中,以便在该方法中进行耗时操作。

3.1 源码分析

对源码的分析,参考第二部分中使用的步骤,可以看出以上两种方式都大致分为5步。下面参考2.2中的执行流程分析如下:

3.1 创建HandlerThread,添加线程名称

HandlerThread的构造方法如下:

```java

//线程优先级 int mPriority; //线程号 int mTid = -1; //Looper对象 Looper mLooper; //Handler对象 private @Nullable Handler mHandler; //只包含线程名称的构造,其默认线程优先级为默认的:0 public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } //包含线程名称和优先级的构造 public HandlerThread(String name, int priority) { super(name); mPriority = priority; }

```

本部分主要是新建HandlerThread类,设置进程名称和优先级。

3.2 开启HandlerThread线程

调用start()后开始执行线程的run()方法,如下所示:

```java

handlerThread.start(); // 开启线程

```

重构后的内容如下:

```java

@Override

public void run() {

// 获取线程号

mTid = Process.myTid();

// 调用prepare()方法,准备MessageQueue

prepare();

// 阻塞等待,查看Looper是否准备完成,其notifyAll()主要针对下面的getLooper()中的wait()方法

synchronized (this) {

mLooper = Looper.myLooper();

notifyAll();

}

// 设置线程优先级

Process.setThreadPriority(mPriority);

// 如果需要自定义处理,可以重写onLooperPrepared()方法

onLooperPrepared();

// 开启loop循环,执行消息的存储和派发

startLooper();

mTid = -1;

}

private void prepare() {

// 实现准备MessageQueue的逻辑

}

private void onLooperPrepared() {

// 实现自定义处理的逻辑,如异步操作等

}

private void startLooper() {

Looper.loop();

}

```

以下是重构后的内容:

```java

mWorkHandler = new Handler(Looper.myLooper()) {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case UPDATE_THREAD1:

Log.i(TAG, "handleMessage: 子线程处理1");

break;

case UPDATE_THREAD2:

Log.i(TAG, "handleMessage: 子线程处理2");

break;

}

}

};

```

主要流程如下:

1. 准备Looper对象:通过`Looper.prepare()`方法开始准备Looper对象。

2. 阻塞等待:使用`synchronized`关键字对代码块进行加锁,以便在准备Looper对象时不会被其他线程干扰。当Looper对象准备完成后,调用`notifyAll()`方法通知所有等待的线程,并释放锁。

3. 获取Looper对象:通过`getLooper()`方法获取已准备好的Looper对象。在该方法中,同样使用`synchronized`关键字对代码块进行加锁,然后使用`while`循环不断检查是否已经完成了Looper的准备。如果Looper尚未准备好,就调用`wait()`方法让当前线程等待;如果Looper已经准备好,就调用`notifyAll()`方法通知所有等待的线程并返回Looper对象。

4. 发送消息:在获取到已准备好的Looper对象后,可以将其用于创建Handler对象,然后通过Handler对象的`sendMessage()`方法发送消息,执行异步的任务处理。

5. 结束线程:调用`HandlerThread`的`quit()`方法或`quitSafely()`方法来结束线程。其中,`quit()`方法是非线程安全的,可能会导致执行效率降低;而`quitSafely()`方法是线程安全的,但可能引起一定的性能损失。

//HandlerThread 重构后的方法:

public boolean quit() {

Looper looper = getLooper();

if (looper != null) {

looper.quit();

return true;

}

return false;

}

public boolean quitSafely() {

Looper looper = getLooper();

if (looper != null) {

looper.quitSafely();

return true;

}

return false;

}

//Looper 重构后的方法:

public void quit(boolean value) {

mQueue.quit(value);

}

MessageQueue的quit方法用于退出消息队列,根据参数safe来判断是否线程安全。如果safe为true,则在移除所有消息之前先移除所有未来的消息;如果safe为false,则直接移除所有消息。

在移除所有消息的过程中,分为线程不安全和线程安全两种方式。线程不安全的方式是遍历所有消息,并置空;线程安全的方式是在回收消息时,判断消息的时间,如果该消息未处理完成则等待处理,否则直接处理(与线程不安全类似)。

以下是重构后的代码:

```java

// MessageQueue

void quit(boolean safe) {

// 判断是否为线程安全

if (safe) {

removeAllFutureMessagesLocked();

} else {

removeAllMessagesLocked();

}

}

// 移除所有消息(线程不安全)

private void removeAllMessagesLocked() {

Message p = mMessages;

while (p != null) {

Message n = p.next;

p.recycleUnchecked();

p = n;

}

mMessages = null;

}

// 移除所有未来消息(线程安全)

private void removeAllFutureMessagesLocked() {

final long now = SystemClock.uptimeMillis();

Message p = mMessages;

if (p != null) {

if (p.when > now) {

removeAllMessagesLocked();

} else {

// ... 其他处理逻辑

}

}

}

```