版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kikitious_Du/article/details/78846327
HandlerThread简介
HandlerThread继承自Thread,所以本质上HandlerThread是一个线程类。
HandlerThread是一种可以使用Handler的Thread。
HandlerThread在内部创建了消息队列,外界通过Handler的消息方式来通知HandlerThread执行一个具体的任务。
HandlerThread使用
① 创建HandlerThread对象
HandlerThread thread = new HandlerThread("my-handler-thread");
② 启动线程
thread.start();
③ 创建Handler对象,传入HandlerThread对象所在线程的Looper对象
Handler downloadHandler = new Handler(thread.getLooper()) {
@Override
public void handleMessage(Message msg) {
//执行具体的耗时任务,如加载网络图片等
//通知主线程刷新UI
mUIHandler.sendMessage(message);
}
};
④ Handler对象发送Message或者Runnable
downloadHandler.sendEmptyMessageDelayed(100, 1000);
全部代码如下:
public class MyHandlerThreadActivity extends BaseActivity {
private static final String TAG = "MyHandlerThreadActivity";
private String url = "https://img-blog.csdn.net/20160903083245762";
private ImageView imageView;
private Handler uiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
imageView.setImageBitmap((Bitmap) msg.obj);
}
};
private HandlerThread thread;
private Handler downloadHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
Log.i(TAG, "Thread.currentThread().getName() = " + Thread.currentThread().getName());
findView();
initTask();
}
private void findView() {
imageView = (ImageView) findViewById(R.id.image);
}
@Override
protected void onResume() {
super.onResume();
downloadHandler.sendEmptyMessageDelayed(100, 1000);
}
private void initTask() {
thread = new HandlerThread("my-handler-thread");
thread.start();
Log.i(TAG, "thread.getName() = " + thread.getName());
//加载网络图片,耗时任务
downloadHandler = new Handler(thread.getLooper()) {
@Override
public void handleMessage(Message msg) {
//加载网络图片,耗时任务
Bitmap bitmap = downloadUrlBitmap(url);
Message message = Message.obtain();
message.what = msg.what;
message.obj = bitmap;
uiHandler.sendMessage(message);
}
};
}
private Bitmap downloadUrlBitmap(String urlString) {
HttpURLConnection conn = null;
BufferedInputStream in = null;
Bitmap bitmap = null;
try {
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
InputStream inputStream = conn.getInputStream();
in = new BufferedInputStream(inputStream, 8 * 1024);
bitmap = BitmapFactory.decodeStream(in);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
@Override
protected void onDestroy() {
super.onDestroy();
thread.quit();
}
}
HandlerThread源码
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;//当前线程持有的Looper对象
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
//name线程名称,priority线程优先级
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
//创建HandlerThread的对象之后,必须先调用start()方法,即会先调用run()方法
//Looper对象创建后,第③步中将这个Looper对象传入Handler对象中
//可以保证此Handler对象中的handleMessage方法执行在异步线程
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();//创建Looper对象
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();//唤醒机制,见下面的getLooper方法
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
//第③步,thread.getLooper()时,在主线程中调用此方法
//而Looper对象的创建是在子线程中
//所以,我们无法保障在调用getLooper方法时Looper已经被创建
//故,只有当线程创建成功&&Looper对象创建成功以后,这里才能获得mLooper的值
public Looper getLooper() {
if (!isAlive()) {//先判断当前线程是否启动,没启动直接返回null
return null;
}
// If the thread has been started, wait until the looper has been created.
// 当线程创建成功后,必须等到Looper对象创建成功以后,这里才能获得mLooper的值
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
//调用Looper的quit方法,最终执行removeAllMessagesLocked()方法
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
//调用Looper的quitSafely方法,最终执行removeAllFutureMessagesLocked()方法
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
//MessageQueue.java中的quit方法
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true;
if (safe) {
//只会清空MessageQueue消息池中所有的延迟消息,
//并将消息池中所有的非延迟消息派发出去让Handler去处理完成后才停止Looper循环
removeAllFutureMessagesLocked();
} else {
//把MessageQueue消息池中所有的消息全部清空,
//无论是延迟消息(延迟消息是指通过sendMessageDelayed或通过postDelayed等方法发送)还是非延迟消息
removeAllMessagesLocked();
}
// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
参考链接: