接触过Android项目开发的小伙伴应该都知道,Handler在Android中占有举足轻重的地位。因为一个项目的开发,多线程的运用是必不可少的,但是如果在异步线程完成某些耗时操作后,想对UI进行操作时,由于Android设计不允许在子线程更新UI,那怎么办?
利用Handler,一个Message发送过去,就可以轻轻松松完成这个操作啦。
对于Handler的应用,大多数场景都是这样。但是假如你想要在Handler处理Message方法中实现异步的操作,又该怎么办呢?有不懂事的小伙伴可能会说,直接使用Handler.post(new Runnable(){});就行啦,如果还有这个想法的,那建议小伙伴还是回去加深一下Handler、Thread、Runnable的理解。当然,还有的小伙伴会说,在Handler的handlerMessage()方法中new一个新的Thread,不就完事了嘛。的确如此,new一个新的Thread来实现异步操作的确没有问题,但假如Handler发送的Message之前有着必要的先后执行顺序,如果每接受到一个Message,就开一个新的线程去操作,那这个应用的线程管理,将会无比复杂,稍不留神,可能就会出现各种问题。
针对以上这些情况,你们的救世主来啦,它就是--HandlerThread!!!
对于HandlerThread,它在API中的解释是这样的:
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对象。但是它有一个使用条件,那就是必须要先执行start()方法
private HandlerThread ht;
private Handler mThreadHandler;
private Activity mActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivity = this;
//init views
mThreadNameView = findViewById(R.id.thread_name);
mUiHandlerBtn = findViewById(R.id.ui_handler_btn);
mHandlerThreadBtn = findViewById(R.id.thread_handler_btn);
mUiHandlerBtn.setOnClickListener(this);
mHandlerThreadBtn.setOnClickListener(this);
//init Handler
ht = new HandlerThread("Handler Thread");
ht.start();
mThreadHandler = new Handler(ht.getLooper());
}
@SuppressLint("HandlerLeak")
private Handler mUIHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "mUIHandler: current thread name: " + Thread.currentThread().getName());
Log.i(TAG, "mUIHandler: current thread is main thread ? "
+ (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()));
showCurrentThreadName(Thread.currentThread());
}
};
private void showCurrentThreadName(final Thread myThread) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mThreadNameView.setText(myThread.getName());
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ui_handler_btn:
mUIHandler.post(new Runnable() {
@Override
public void run() {
Log.i(TAG, "mUIHandler run on new Runnable, current thread is "
+ Thread.currentThread().getName());
}
});
mUIHandler.sendEmptyMessage(0);
break;
case R.id.thread_handler_btn:
mThreadHandler.post(new Runnable() {
@Override
public void run() {
showCurrentThreadName(Thread.currentThread());
}
});
break;
}
}
通过执行可以发现,在主线程创建的UIHandler,在handlerMessage或者是new Runnable(){},均是在主线程执行的,而通过HandlerThread的Looper创建的ThreadHandler,则是运行在“Handler Thread”此线程中。
至此,简单的HandlerThread讲解以及运用,就基本完成了。
在此附上本人的Demo链接 https://gitee.com/meinkonone/HanderThread