Android多线程通信:HandlerThread详解
## 一、背景介绍
在之前的博客中,我们已经学习了关于Android多线程中通信的基础概念和基本用法,通过现实世界两个人写信交流的过程来理解这些概念。然而,这套完整的细节确实很繁琐。幸运的是,Android为我们提供了一个简化的API——HandlerThread,通过使用HandlerThread,我们可以以一种简单的方式开启线程、进行线程通信。接下来,我们将详细介绍HandlerThread的使用方法。
## 二、HandlerThread简介
1. 参考文档:http://developer.android.com/reference/android/os/HandlerThread.html
2. 源码地址:Android-22源码中的`android/os/HandlerThread.java`文件
3. 重点方法:
- `protected void onLooperPrepared()`:在拓展类中需要重写的方法,完成准备工作,一般是对Handler进行定义。
- `public void run()`:在拓展HandlerThread时,如果要override run方法一定要记得调用父类的run()。
## 三、如何使用HandlerThread?
### 步骤1:创建HandlerThread实例
```java
private static final String TAG = "MyHandlerThread";
private HandlerThread mHandlerThread;
private Handler mHandler;
// ...
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start(); // 启动线程
mHandler = new Handler(mHandlerThread.getLooper()) { // 获取Looper并初始化Handler
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
// 处理消息1的逻辑
break;
case 2:
// 处理消息2的逻辑
break;
default:
break;
}
}
};
```
### 步骤2:发送消息给HandlerThread中的Handler进行处理
```java
Message message = Message.obtain(); // 获取Message对象
message.what = 1; // 设置消息类型为1或2
sendMessageToHandler(message); // 将消息发送给Handler进行处理
```
### 步骤3:从Handler接收消息并处理
```java
@Override
public void onMessageReceived(Message msg) {
int what = msg.what;
switch (what) {
case 1:
// 处理消息1的逻辑
break;
case 2:
// 处理消息2的逻辑
break;
default:
break;
}
}
```
### 步骤4:移除消息监听器(可选)
当不再需要接收消息时,可以移除消息监听器以避免内存泄漏。
在这篇文章中,我们将使用HandlerThread来演示如何在Android中创建线程。我们将通过一个简单的示例来说明HandlerThread的用法。首先,我们需要创建一个扩展的HandlerThread类,并在其中实现post方法以便与主线程进行通信。接下来,我们将在Activity中使用这个类,并通过Logcat打印日志来观察线程的执行情况。
1. 创建扩展的HandlerThread类:
```java
public class MyHandlerThread extends HandlerThread {
private static final String TAG = "MyThread";
public MyHandlerThread(String name) {
super(name);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
Handler handler = new MyHandler(getLooper());
getThreadPool().execute(handler);
}
private static class MyHandler extends Handler {
public MyHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "handlerRequest: testing HandlerThread, thread: " + Thread.currentThread().getName());
// 处理消息的逻辑
Log.d(TAG, "message is handled, thread: " + Thread.currentThread().getName());
if (msg.what == WHAT_UPDATE_DATA) {
// do something;
} else if (msg.what == WHAT_SHOW_TOAST) {
Toast.makeText(MyHandlerThread.this.getApplicationContext(), msg.arg1, Toast.LENGTH_SHORT).show();
}
}
}
}
```
2. 在Activity中使用MyHandlerThread类:
```java
public class MainActivity extends AppCompatActivity {
private static final int WHAT_UPDATE_DATA = 0;
private static final int WHAT_SHOW_TOAST = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LogcatPrinter logcatPrinter = new LogcatPrinter("MyThread");
new MyHandlerThread("MyThread").start(); //开启线程
}
private static class LogcatPrinter implements Runnable {
private String tag;
private boolean running = true;
private final Looper mLooper;
private volatile boolean mCancelled = false;
private Message mMessage; //用于传递信息给子线程的对象;
private MyHandlerThread myHandlerThread; //自定义的线程对象;
private static MyHandlerThread myHandlerThreadInstance = null; //线程实例对象;
private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2 + 1; //线程池大小设置为可用的处理器数量乘以2加1;
private static BlockingQueue