HandlerThread是Android API提供的一个方便、便捷的类,使用它我们可以快速的创建一个带有Looper的线程。Looper可以用来创建Handler实例。注意:start()仍然必须被调用。

以下是HandlerThread使用的示例代码:

```java

import android.os.Handler;

import android.os.Looper;

import android.util.Log;

public class HandlerDemo {

private static final String TAG = "HandlerDemo";

public static void main(String[] args) {

// 创建HandlerThread

HandlerThread handlerThread = new HandlerThread("MyHandlerThread");

handlerThread.start();

// 获取Looper

Looper looper = handlerThread.getLooper();

// 在Looper中创建Handler并处理消息

Handler handler = new Handler(looper) {

@Override

public void handleMessage(android.os.Message msg) {

super.handleMessage(msg);

Log.d(TAG, "收到消息:" + msg.what);

}

};

// 发送消息到HandlerThread中的Handler进行处理

Message message = handlerThread.obtainMessage();

message.what = 1;

message.obj = "Hello, Handler!";

handler.sendMessage(message);

}

}

```

在上述代码中,首先创建了一个名为"MyHandlerThread"的HandlerThread对象,并通过start()方法启动线程。然后通过getLooper()方法获取到该线程的Looper对象。接下来,在Looper中创建了一个自定义的Handler对象,并重写了handleMessage()方法来处理接收到的消息。最后,通过handlerThread.obtainMessage()方法获取一个消息对象,并设置了消息的类型和内容,然后通过handler.sendMessage()方法将消息发送给HandlerThread中的Handler进行处理。

以下是重构后的代码:

```java

package com.zpengyong.hand;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.Looper;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

public class MainActivity extends Activity {

private final static String TAG = "MainActivity";

private Button mGet;

private TextView mResult;

protected final int MSG_GET = 1;

protected final int MSG_RESULT = 2;

private HandlerThread mHandlerThread;

//子线程中的Handler实例。

private Handler mSubThreadHandler;

//与Ui线程绑定的Handler实例。

private Handler mUiHandler = new Handler() {

public void handleMessage(Message msg) {

Log.i(TAG, "mUiHandler handleMessage thread:" + Thread.currentThread());

switch (msg.what) {

case MSG_RESULT:

mResult.setText((String) msg.obj);

break;

default:

break;

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Log.i(TAG, "onCreate thread:" + Thread.currentThread());

mGet = (Button) findViewById(R.id.get);

mGet.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

mSubThreadHandler.sendEmptyMessage(MSG_GET);

}

});

mResult = (TextView) findViewById(R.id.result);

initHandlerThraed();

}

private void initHandlerThraed() {

//创建HandlerThread实例

mHandlerThread = new HandlerThread("handler_thread");

//开始运行线程

mHandlerThread.start();

//获取HandlerThread线程中的Looper实例

Looper loop = mHandlerThread.getLooper();

//创建Handler与该线程绑定。

mSubThreadHandler = new Handler(loop) {

public void handleMessage(Message msg) {

Log.i(TAG, "mSubThreadHandler handleMessage thread:" + Thread.currentThread());

switch (msg.what) {

case MSG_GET:

try { //模拟延时处理

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

double number = Math.random();

String result = "number:" + number; //向ui线程发送消息,更新ui。

Message message = new Message();

message.what = MSG_RESULT;

message.obj = result;

mUiHandler.sendMessage(message);

break;

default:

break;

}

}

};

}

@Override

protected void onDestroy() {

super.onDestroy();

Log.i(TAG, "onDestroy"); //退出HandlerThread的Looper循环。mHandlerThread.quit();

上述代码相对简单,功能也较为基础。在此基础上,我们可以进行一些扩展和优化。

首先,在Activity创建时调用`initHandlerThraed()`函数:

```java

private Handler mSubThreadHandler;

private Handler mUiHandler;

private HandlerThread mHandlerThread;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initHandlerThraed();

}

private void initHandlerThraed() {

mSubThreadHandler = new Handler(new HandlerThread("sub_thread").start());

mUiHandler = new Handler(Looper.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

// 在主线程中更新UI界面

switch (msg.what) {

case 1:

// TODO: 根据消息内容更新UI界面

break;

}

}

};

}

```

接下来,多次点击按钮,打印信息如下所示:

```yaml

07-13 05:15:07.662: I/MainActivity(1472): onCreate thread:Thread[main,5,main] 07-13 05:15:45.382: I/MainActivity(1472): mSubThreadHandler handleMessage thread:Thread[handler_thread,5,main] 07-13 05:15:46.402: I/MainActivity(1472): mUiHandler handleMessage thread:Thread[main,5,main] 07-13 05:15:46.412: I/MainActivity(1472): mSubThreadHandler handleMessage thread:Thread[handler_thread,5,main] 07-13 05:15:47.412: I/MainActivity(1472): mUiHandler handleMessage thread:Thread[main,5,main] .....

```

点击按钮,向`mSubThreadHandler`发送消息,`mSubThreadHandler`接收到消息后进行处理。从打印的信息可以看出,`mSubThreadHandler`的`handleMessage`方法运行在子线程中。模拟耗时操作,生成随机数,然后向主线程中的`mUiHandler`发送消息(Message)。`mUiHandler`的`handleMessage`方法运行在主线程,可以用来更新UI界面。当Activity销毁时,调用`mHandlerThread.quit()`退出`HandlerThread`的Looper循环。效果图如下:

```markdown

2. HandlerThread源码分析

HandlerThread是Android系统中的一个类,它继承自Thread类。我们可以通过查看源码来了解HandlerThread的构造方法和run()方法。

首先,我们来看一下HandlerThread的构造方法:

```java

public class HandlerThread extends Thread {

int mPriority;

int mTid = -1;

Looper mLooper;

// 参数为线程名称

public HandlerThread(String name) {

super(name);

mPriority = Process.THREAD_PRIORITY_DEFAULT;

}

// 参数为线程名称和优先级

public HandlerThread(String name, int priority) {

super(name);

mPriority = priority;

}

}

```

HandlerThread提供了两个构造方法,分别是:

1. `HandlerThread(String name)`:参数为线程名称,线程优先级默认为`Process.THREAD_PRIORITY_DEFAULT`。

2. `HandlerThread(String name, int priority)`:参数为线程名称和设置的线程优先级。

接下来,我们来看一下线程运行的run()方法:

```java

@Override

public void run() {

mLooper = new Looper();

mTid = getId();

}

```

在run()方法中,首先创建了一个Looper对象,然后获取了当前线程的ID并赋值给mTid。这样,HandlerThread就可以根据mTid来处理消息队列中的任务。

protected void onLooperPrepared() {

}

@Override

public void run() {

//获取进程id

mTid = Process.myTid();

//创建Looper实例

Looper.prepare();

synchronized (this) {

//获取当前线程的Looper实例

mLooper = Looper.myLooper();

notifyAll();

}

//设置线程优先级

Process.setThreadPriority(mPriority);

onLooperPrepared();

//开始循环

Looper.loop();

mTid = -1;

}

此方法返回与此线程关联的Looper。 如果此线程未启动或由于任何原因isAlive()返回false,此方法将返回null。

```java

public Looper getLooper() {

if (!isAlive()) {

return null;

}

// 如果这个线程已经启动,将会被阻塞,直到mLooper被初始化为止。

synchronized (this) {

while (isAlive() && mLooper == null) {

try {

wait();

} catch (InterruptedException e) {

}

}

}

return mLooper;

}

```

在HandlerThread的run()方法中,我们会为该线程创建一个Looper实例并赋值给mLooper变量。getLooper()方法则是在主线程中调用,用于获取与该线程绑定的Looper实例。如果线程未启动或者已经死亡(isAlive()返回false),则该方法会返回null。

接下来,通过该looper实例创建Handler:

```java

// 创建Handler与该线程绑定。 mSubThreadHandler = new Handler(loop)

```

你可能会好奇为什么要这样长久Handler而不是“new Handler()“这样呢?因为我们要创建的Handler要与子线程绑定到一起,要处理子线程中的消息,所以要通过子线程中的looper(有线程对应的消息队列)实例创建Handler。这样通过mSubThreadHandler发送的消息会添加到子线程中的消息队列中,然后Looper实例消息进行分发,交给mSubThreadHandler进行处理。

```java

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;

}

```

HandlerThread是Android中用于处理本地IO读写操作(如数据库、文件)的线程。它适合在单线程+异步队列的形式下运行,因为本地IO操作大多数耗时在毫秒级别,这样的方式不会对后面的请求产生较大阻塞。而网络操作相对耗时,容易阻塞后续请求,因此在HandlerThread中不适合加入网络操作。

quit和quitSafely方法都是用于退出HandlerThread的消息循环。它们都调用Looper的quit或quitSafely方法,但它们的区别在于:

- quit方法会将消息队列中的所有消息移除(包括延迟消息和非延迟消息)。

- quitSafely方法只会将消息队列中的所有延迟消息移除,而非延迟消息则会被派发给Handler去处理。与quit相比,quitSafely在清空消息之前会派发所有的非延迟消息,因此更加安全。