HandlerThread 用法

时间:2023-03-08 21:30:38
HandlerThread 用法

HandlerThread最大的优势在于引入MessageQueue概念,可以进行多任务队列管理。

  HandlerThread背后只有一个线程,所以任务是串行依次执行的。串行相对于并行来说更安全,各任务之间不会存在多线程安全问题。

  HandlerThread所产生的线程会一直存活,Looper会在该线程中持续的检查MessageQueue,并开启消息处理的循环。这一点和Thread(),AsyncTask都不同,thread实例的重用可以避免线程相关的对象的频繁重建和销毁。 getLooper().quit();来退出这个线程,其实原理很简单,就是改变在消息循环里面标志位,退出整个while循环,使线程执行完毕。

部分 测试代码如下:

public void onCreate(Bundle savedInstanceState) {

  1. super.onCreate(savedInstanceState);
  2. setContentView(R.layout.main);
  3. tv_name = (TextView) findViewById(R.id.tv_name);
  4. btn_name = (Button) findViewById(R.id.btn_name);
  5. Log.i(TAG, "==================main thread:" + Thread.currentThread().getName());
  6. final HandlerThread mHandlerThread = new HandlerThread("handlerThread");
  7. mHandlerThread.start();
  8. // Handler的handlerMessage方法在主线程执行还是在子线程执行,取决于创建Handler时传递给Handler的looper
  9. final MyHandler mHanlder = new MyHandler(mHandlerThread.getLooper());
  10. btn_name.setOnClickListener(new OnClickListener() {
  11. @Override
  12. public void onClick(View v) {
  13. mHanlder.sendEmptyMessage(1);
  14. try {
  15. Thread.sleep(3000);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. mHandlerThread.getLooper().quit();
  20. }
  21. });
  22. }
  23. class MyHandler extends Handler {
  24. public MyHandler(Looper looper) {
  25. super(looper);
  26. }
  27. @Override
  28. public void handleMessage(Message msg) {
  29. Log.i(TAG, "==================" + Thread.currentThread().getName());
  30. // 输出内容为: ==============handlerThread
  31. //tv_name.setText("hello, this is the first message from handler");
  32. super.handleMessage(msg);
  33. }
  34. }

不过要注意:要想更新界面内容,还是需要使用主线程的Looper,不然的话还是会抛错误。