Android 开发我们在主线中不能过耗时操作,像类似网络请求、数据库查询等耗时操作我们都要在子线程中进行,但是线程也是一种系统资源,频繁的new Thread() 肯定会有一定的资源消耗,所以除了用线程池来进行线程管理外,Android还给我们提供里HandlerThread 来进行耗时操作。
HandlerThread 是Thread的一个子类,不同的是,它内部创建了Looper,有了轮询器我们就可以创建Handler 从而对不同消息进行不同的处理。
(1)HandlerThread 的用法
public class MainActivity extends AppCompatActivity {
private static final String TAG = "HANDLER_THREAD";
private HandlerThread handlerThread;
private Handler tHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnTest1 = (Button) findViewById(R.id.btn_test1);
Button btnTest2 = (Button) findViewById(R.id.btn_test2);
handlerThread = new HandlerThread("H_Thread");
handlerThread.start();
tHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG,((String)msg.obj)+ "当前线程" + Thread.currentThread().getName());
}
};
btnTest1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = tHandler.obtainMessage();
message.obj="Main";
tHandler.sendMessage(message);
}
});
btnTest2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Message message = tHandler.obtainMessage();
message.obj="Child";
tHandler.sendMessage(message);
}
}).start();
}
});
}
以上代码打印的结果是:
由此可见:无论是在主线程还是子线程中发出请求,都会在handlerThread 中进行耗时操作。
2)HandlerThread 源码
HandlerThread 有两个构造方法:
其中的参数分别为:该线程的名称和该线程的优先级别。
在我们创建HandlerThread 对象后,在调用getLooper()来获取Looper前一定不要忘记调用它的start()方法,为什么呢?我们看下他的run()方法就知道了。
可以看到在run()方法中,HandlerThread才创建了轮询器Looper 并调用了Looper.loop()进行轮询。如果你在调用getLooper()前,你没有调用start()来启动该线程,再调用getLooper()即返回null,源码如下:
在不需要HandlerThread处理消息的时候,调用quit()方法或者quitSafely()方法来使轮询器停止轮询。
他们之间不同的是,当调用quit()方法后,looper 会立刻停止轮询,即便消息队列中还有未处理的消息,而quitSafely()会等待消息队列中剩下的消息处理完毕后才会停止轮询。