HandlerThread源码
它是一个Thread的子类,源码很简单,只有100多行代码
1、 run()
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); //创建了一个Looper对象
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared(); //调用了 onLooperPrepared ,开启Looper.loop前的准备
Looper.loop(); // 开启了Loop无限循环
mTid = -1;
}
可以看到这个方法,run方法创建了一个Looper,在调用了onLooperPrepared()方法后,开启了loop循环。我们需要做的就是重写onLooperPrepared() 做一些初始化工作。
问题:
这里开启一个Looper.loop()循环有什么作用呢? 在Handler源码解析中我们可以了解到,loop循环其实就是在Looper对象的MessageQueue对象中无限的取消息,调用Message.target.dispatchMessage方法来处理消息。由此我们可以想到HandlerThread的实际应用,就是通过一个Handler发送消息到这个线程的MessageQueue对象中,然后利用它已经写好的Looper.loop()方法无限循环处理消息。
HandlerThread应用
1、HandlerThread的用处
HandlerThread主要用于处理耗时的多任务操作,比如多任务下载或者多个文件的IO读写
2、如何使用呢?下面模仿写一个多任务下载的HandlerThread
public class DownloadThread extends HandlerThread implements Handler.Callback {
private Handler mWorkHandler;
private Handler mUIHandler;
private List<String> mDownloadUrlList;
private final String KEY_URL = "url";
public static final int TYPE_START = 1;
public static final int TYPE_FINISHED = 2;
public DownloadThread setDownloadUrlList(List<String> downloadUrlList) {
mDownloadUrlList = downloadUrlList;
return this;
}
public DownloadThread setUIHandler(Handler UIHandler) {
mUIHandler = UIHandler;
return this;
}
public DownloadThread(String name) {
super(name);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mWorkHandler = new Handler(getLooper(), this);
if (mUIHandler == null){
throw new IllegalArgumentException("Not set UIHandler! ");
}
if (mDownloadUrlList == null || mDownloadUrlList.size() <= 0){
throw new IllegalArgumentException("the downloadUrlLsit is null, Please set DownloadUrlList! ");
}
for (String url : mDownloadUrlList) {
Message obtain = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString(KEY_URL,url);
obtain.setData(bundle);
mWorkHandler.sendMessage(obtain);
}
}
@Override
public boolean handleMessage(Message msg) {
if (msg == null || msg.getData() == null){
return false;
}
String downloadUrl = msg.getData().getString(KEY_URL);
Message startMessage = mUIHandler.obtainMessage(TYPE_START);
mUIHandler.sendMessage(startMessage);
//todo download code
Message finishMessage = mUIHandler.obtainMessage(TYPE_FINISHED);
mUIHandler.sendMessage(finishMessage);
return false;
}
@Override
public boolean quitSafely() {
mUIHandler = null;
return super.quitSafely();
}
}
这里模仿写了一个多任务下载的HandlerThread,这是我能想到的最好的应用场景。如果你有比较好的应用场景,请告诉我 谢谢。