HandlerThread 使用以及源码分析

  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()会等待消息队列中剩下的消息处理完毕后才会停止轮询。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值