官方描述:
Handy class for starting a new thread that has a looper. The looper can then be used to
create handler classes. Note that start() must still be called.
翻译:大致意思是HandlerThread能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。(线程中的
Looper)需要注意的是,新建的时候需要被回调。
回顾普通用法
我们先来看看在使用HandlerThread之前使用Handler 和Thread的配合使用例子
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// 这里处理消息
}
};
Looper.loop();
}
可以看到代码很多很麻烦,google的工程师也注意到了这一点于是给我们封装了一下,方便我们使用并且减少不必要的错误
基本使用用例
package com.example.double2.handlerthreadtest;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView tvMain;
private HandlerThread mHandlerThread;
//子线程中的handler
private Handler mThreadHandler;
//UI线程中的handler
private Handler mMainHandler = new Handler();
//以防退出界面后Handler还在执行
private boolean isUpdateInfo;
//用以表示该handler的常熟
private static final int MSG_UPDATE_INFO = 0x110;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMain = (TextView) findViewById(R.id.tv_main);
initThread();
}
private void initThread()
{
mHandlerThread = new HandlerThread("check-message-coming");
mHandlerThread.start();
mThreadHandler = new Handler(mHandlerThread.getLooper())
{
@Override
public void handleMessage(Message msg)
{
update();//模拟数据更新
if (isUpdateInfo)
mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
};
}
private void update()
{
try
{
//模拟耗时
Thread.sleep(2000);
mMainHandler.post(new Runnable()
{
@Override
public void run()
{
String result = "每隔2秒更新一下数据:";
result += Math.random();
tvMain.setText(result);
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
@Override
protected void onResume()
{
super.onResume();
//开始查询
isUpdateInfo = true;
mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
@Override
protected void onPause()
{
super.onPause();
//停止查询
//以防退出界面后Handler还在执行
isUpdateInfo = false;
mThreadHandler.removeMessages(MSG_UPDATE_INFO);
}
@Override
protected void onDestroy()
{
super.onDestroy();
//释放资源
mHandlerThread.quit();
}
}
源码介绍
HandlerThread的源码非常的简单看起来 so easy!
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
//也可以指定线程的优先级,注意使用的是 android.os.Process 而不是 java.lang.Thread 的优先级!
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
// 子类需要重写的方法,在这里做一些执行前的初始化工作
protected void onLooperPrepared() {
}
//获取当前线程的 Looper
//如果线程不是正常运行的就返回 null
//如果线程启动后,Looper 还没创建,就 wait() 等待 创建 Looper 后 notify
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) { //循环等待
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
//调用 start() 后就会执行的 run()
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); //帮我们创建了 Looepr
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll(); //Looper 已经创建,唤醒阻塞在获取 Looper 的线程
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop(); //开始循环
mTid = -1;
}
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;
}
public int getThreadId() {
return mTid;
}
}
注意点:
①HandlerThread 本质还是个 Thread,创建后别忘了调用 start()。
②在 run() 方法中创建了 Looper,调用 onLooperPrepared 后开启了循环
③我们要做的就是在子类中重写 onLooperPrepared,做一些初始化工作
④在创建 HandlerThread 时可以指定优先级,注意这里的参数是 Process.XXX 而不是 Thread.XXX