Android学习笔记:HandlerThread 和IntentService的使用及源码

本文详细介绍了Android中的HandlerThread,包括其产生背景、实现原理及使用方法。HandlerThread通过绑定Looper简化了子线程中使用Handler的过程,提高了系统资源利用效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HandlerThread

HandlerThread是一个线程,内部并没有Handler,而是一个为子线程中可以使用Handler而创建了Looper并开启了Looper.loop()循环的线程。也就是说HandlerThread绑定了Looper。

产生背景

子线程开启进行耗时操作实现方式很简单,但是为什么Android还会专门为此封装一个类来操作呢,直接写个线程也没多写多少代码,但是想想,线程的创建和销毁也是需要消耗系统资源的,一次的创建销毁不会有太大的问题,假如多次的数据操作时,多次的创建和销毁线程就会很耗系统资源了。
但是使用HandlerThread也有个缺点,消息队列处理消息是串行的,实际只是一个线程处理多个任务,效率偏低、

实现原理

HandlerThread的源码非常简短,只有短短的150行,创建逻辑也很清晰
和我们平时在子线程开启Looper,使用Handler的方式类似,HandlerThread在run()方法里绑定了Looper,方便了想使用异步消息机制的场景


    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

并且提供了退出的方法,当我们不需要线程运行的时候,可以调用退出方法,退出。

如何使用

HandlerThread的提供了onLooperPrepared()方法,表示Looper已经创建,此时可以在该方法里创建Handler来发送消息,此方法在HandlerThread的run()方法里调用的,当然HandlerThread还提供了获取Looper的方法,我们可以在创建Handler的时候,接收此Looper对象来绑定该线程的looper,效果是一样的

        //IntentService内部Handler的使用体现
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);

IntentService

Android中四大组件内都是不可以进行耗时的操作的,而因为Service的优先级比较高,并且往往用来进行一些优先级比较高的后台任务。所以Service + HandlerThread 是一个很好的组合,所有就有了IntentService。
- IntentService是继承Service的一个抽象类,使用他需要继承IntentService,当IntentService第一启动时,会走onCreate()的生命周期,此时初始化了HandlerThread和Handler(ServiceHandler)将Handler和子线程的Looper绑定了,这样我们就可以在这个Service所提供的方法onHandleIntent()里执行一个耗时等后台任务了。

@Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

我们在启动Service时使用Intent传递了数据,当startService()时,Intent携带数据,会走到 onStartCommand(Intent intent, int flags, int startId) 该方法最终经过IntentService内部的Handler(ServiceHandler),用Message将Intent携带发送出去。

 @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

以为ServiceHandler此时绑定的是HandlerThread线程中的Looper,所以ServiceHandler的handleMessage()是在HandlerThread线程中执行的,

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

这样我们继承IntentService后重写了onHandleIntent(Intent intent)便可以根据Intent的值做相应的处理,此方法是执行在子线程的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值