美文网首页
3.3异步消息处理机制-HandlerThread

3.3异步消息处理机制-HandlerThread

作者: 205蚁 | 来源:发表于2018-11-09 10:44 被阅读0次

HandlerThread

    1. handlerThread是什么
    1. handlerThread源码解析

1.handlerThread是什么

    1. 产生背景:
      • 开启Thread子线程进行耗时操作
      • 多次创建和销毁线程是很耗系统资源的
    1. handler+thread+looper
      • 是一个thread内部有looper
      • 在子线程中要想使用handler,必须现有looper,创建prepare,new Handler,loop();
    1. 特点
        1. HandlerThread本质上是一个线程类,它继承了Thread
        1. HandlerThead有自己的内部Looper对象,可以进行looper循环
        1. 通过获取HandlerThread的looper对象传递给Handler,可以在handleMessage方法中执行异步任务
        1. (由于Handler的默认绑定的是UI线程的消息队列,对于那些非UI线程想使用消息机制,HandlerThread是最合适的)
          优点是不会有阻塞,减少了对性能的消耗,缺点是不能同时进行多任务的处理,需要等待处理。处理效率低。
        1. 与线程池注重并发不同,HandlerThread是一个串行队列,HandlerThread背后只有一个线程

2.HandlerThread源码解析

  • public class HandlerThread extends Thread{}



![图].jpg](https://img.haomeiwen.com/i1976436/b685ef3b05683c64.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

HandlerThread UML

#mLooper:Looper
+mPriority:int
+mTid:-1;
--------------------
onLooperPrepared()空方法。这个方法必须在loop后
run()
getLooper();
quit()
quitSafely()
    1. 构造 name,priority优先级
    • mPriority = Process.THREAD_PRIORITY_DEFAULT;
    • run:
public void run(){
      Looper.prepare();
      synchronized(this){
        mLooper = Looper.myLooper();
        notifyAll();//线程通讯,通知当前的等待的线程(在下面的getLooper方法中的 wait)
      }
          Process.setThreadPriority(mPriority);//设置线程优先级可以解决一部分线程安全,内存泄露问题---------
      onLooperPrepared();
      Looper.loop();
    mTid = -1;
}
public Looper getLooper(){
    if(!isAlive()){
        return null;
    }
    synchronized(this){
        while(isAlive()&&mLooper==null){
            try{
                wait();
            }catch(InterruptedException e){
            }
        }
    }
    return mLooper;
}   

为什么:Process.setThreadPriority(mPriority);//设置线程优先级可以解决一部分线程安全,内存泄露问题----不解中

  • 我们在获取mLooper时存在一个同步的问题,只有在线程创建成功,looper对象也创建成功,通过notifyAll通知不再等待
public boolean quit(){
Looper looper = getLooper();
if(looper!=null){
    looper.quit();
    return true;
}
return false;
}
  • quitSafely 即上面方法走looper.quitSafely(),使Looper退出消息循环

使用:

    1. HandlerThread mHandlerThread = new HandlerThread("名称");
    1. mHandlerThread.start();//开启线程
    1. Handler mHandler = new Handler(mHandlerThread.getLooper())
public class MainActivity extends AppCompatActivity {

    private HandlerThread myHandlerThread ;
    private Handler handler ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建一个线程,线程名字:handler-thread
        myHandlerThread = new HandlerThread( "handler-thread") ;
        //开启一个线程
        myHandlerThread.start();
        //在这个线程中创建一个handler对象
        handler = new Handler( myHandlerThread.getLooper() ){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //这个方法是运行在 handler-thread 线程中的 ,可以执行耗时操作
                Log.d( "handler " , "消息: " + msg.what + "  线程: " + Thread.currentThread().getName()  ) ;

            }
        };

        //在主线程给handler发送消息
        handler.sendEmptyMessage( 1 ) ;

        new Thread(new Runnable() {
            @Override
            public void run() {
             //在子线程给handler发送数据
             handler.sendEmptyMessage( 2 ) ;
            }
        }).start() ;

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        //释放资源
        myHandlerThread.quit() ;
    }
}

相关文章

网友评论

      本文标题:3.3异步消息处理机制-HandlerThread

      本文链接:https://www.haomeiwen.com/subject/hxynxqtx.html