1. Fundamentals
HandlerThread是一个内部包含Thread,Looper,MessageQueue的线程。HandlerThread 开启之后,它就会创建一个Looper和MessageQueue的队列,等待处理发送过来的消息。
Eg:
HandlerThread handlerThread = new HandlerThread("handlerthread");
handlerThread.start();
// 实例化Handler时,使用HandlerThread的Looper,这样实例化后的Handler属于HandlerThread线程中的,Handler发送的message就会到HandlerThread(Worker Thread)的MessageQueue中,
// 然后在Handler的handleMessage方法中处理发送来的message
mHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// TODO: process message
}
}
如果在HandlerThread开始之前有其他额外的需要设置的,那么需要重写HandlerThread.onLooperPrepared()方法,这个方法在Looper被prepared时候会在background thread中调用。例如,我们可以在onLooperPrepared()方法中创建一个Handler,辅助HandlerThread处理消息。
Eg:
public class MyHandlerThread extends HandlerThread {
private final String TAG = MyHandlerThread.class.getSimpleName();
private Handler mHandler = null;
public MyHandlerThread(String name) {
super("myhandlerthread", Process.THREAD_PRIORITY_BACKGROUND);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Log.i(TAG, "MyHandlerThread # onLooperPrepared # what is 1");
break;
}
}
};
}
public void sendMessage1() {
mHandler.sendEmptyMessage(1);
}
}
2. Lifecycle
一个正在运行的HandlerThread实例对象处理接收到Message直到它被终止,一个终止的HandlerThread不能重用。
Creation
构造方法:
HandlerThread(String name)
HandlerThread(String name, int priority)
Execution
调用HandlerThread.start()方法开始运行
Reset
message queue能够被重置,重置会删除message queue中所有待处理的message,但是那些已经被diapatch出去或者正在执行的message不受影响,同时这个thread还是alive的,也能处理新发生来的message。
Eg:
public void resetHandlerThread() {
mHandler.removeCallbackAndMessages(null);
}
Termination
第一种方法:
调用HandlerThread的quit()或者quitSafely()方法来终止,调用这个方法相当于终止了Looper。
Eg:
public void stopHandlerThread(HandlerThread handlerThread) {
handlerThread.quit();
// 调用interrupt()方法,这样HandlerThread就会取消正在执行的message
handlerThread.interrupt();
}
第二种方法:
通过Handler发送一个终止任务来退出Looper,从而终止HandlerThread
Eg:
handler.post(new Runnable() {
@Override
public void run() {
Looper.myLooper().quit();
}
});
3. Demo
因为HandlerThread中MessageQueue是线性处理的,因此可以依赖这个性质,使用HandlerThread处理有顺序要求的任务。
例如使用HandlerThread处理有顺序要求的网络请求,当同一个网络请求返回成功后,才能进行下一个网络请求。
Eg:
public class ChainedNetworkActivity extends Activity {
private static final int DIALOG_LOADING = 0;
private static final int SHOW_DIALOG = 1;
private static final int DISMISS_DIALOG = 2;
private DialogHandler dialogHandler = null;
private NetworkHandlerThread networkHandlerThread = null;
private static class DialogHandler extends Handler {
private WeakReference<ChainedNetworkActivity> activity = null;
public DialogHandler(ChainedNetworkActivity activity) {
this.activity = new WeakReference<ChainedNetworkActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SHOW_DIALOG:
if (activity != null) {
activity.get().showDialog(DIALOG_LOADING);
}
break;
case DISMISS_DIALOG:
if (activity != null) {
activity.get().dismissDialog(DIALOG_LOADING);
}
break;
}
}
}
private class NetworkHandlerThread extends HandlerThread {
private final int STATE_A = 1;
private final int STATE_B = 2;
private Handler handler = null;
public NetworkHandlerThread() {
super("networkhandlerthread", Process.THREAD_PRIORITY_BACKGROUND);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
handler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case STATE_A:
dialogHandler.sendEmptyMessage(SHOW_DIALOG);
String resultA = network1();
if (resultA != null) {
// 当第一个网络请求成功后,进行下一个
sendMessage(obtainMessage(STATE_B, resultA));
} else {
dialogHandler.sendEmptyMessage(DISMISS_DIALOG);
}
break;
case STATE_B:
network2((String) msg.obj);
dialogHandler.sendEmptyMessage(DISMISS_DIALOG);
break;
}
}
};
// 开始一个网络请求
handler.sendEmptyMessage(STATE_A);
}
private String network1() {
SystemClock.sleep(1000);
return "State 1";
}
private String network2(String preResult) {
SystemClock.sleep(1000);
return preResult + " - State B";
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialogHandler = new DialogHandler(this);
networkHandlerThread = new NetworkHandlerThread();
networkHandlerThread.start();
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case DIALOG_LOADING:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Loading...");
dialog = builder.create();
break;
}
return dialog;
}
@Override
protected void onDestroy() {
super.onDestroy();
networkHandlerThread.quit();
}
}