IntentService的使用以及源码解析

简介

IntentService主要用来异步处理耗时的工作,客户端通过调用startService(Intent)调用服务,使用工作线程依次处理每个 Intent,并在工作结束时自行停止,IntentService是抽象类,如果使用,则需要继承IntentService并重写onHandleIntent方法。

它的所有请求都在单个工作线程上处理——它们可能需要尽可能长的时间(并且不会阻塞应用程序的主循环),但一次只会处理一个请求。

注意,IntentService 受 Android 8.0(API 级别 26)施加的所有限制与约束,在 Android 8.0 或更高版本上运行时使用作业而不是服务JobIntentService。

使用

创建服务

创建JobService继承IntentService。

public class JobService extends IntentService {

    private static final String TAG = "JobService";


    public JobService() {
        //注意这里需要给父类传一个名称。
        super("jobService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        try {
            String job = intent.getStringExtra("job");
            Log.e(TAG, "onHandleIntent: 正在执行:" + job+"-"+this);

            //模拟耗时操作
            Thread.sleep(3000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

启动服务”做工作“

//注意这里连续启动了三个工作。
private void testIntentService(){
        for (int i = 0; i < 3; i++) {
            Intent intent = new Intent(this, JobService.class);
            intent.putExtra("job", "job" + i);

            startService(intent);
        }
    }

输出结果

//log中证明是同一个服务对象
2022-09-04 00:02:19.567 6897-6921/com.example.testannotation E/JobService: onHandleIntent: 正在执行:job0-com.example.testannotation.JobService@c67c661
2022-09-04 00:02:22.569 6897-6921/com.example.testannotation E/JobService: onHandleIntent: 正在执行:job1-com.example.testannotation.JobService@c67c661
2022-09-04 00:02:25.571 6897-6921/com.example.testannotation E/JobService: onHandleIntent: 正在执行:job2-com.example.testannotation.JobService@c67c661

使用总结

IntentService会依此执行客户端发过来的任务,直至任务结束才会停止服务,这些在IntentService的源码中可以得到验证。

IntentService源码

IntentService的源码很少,所以备注信息都写到代码中了。

public abstract class IntentService extends Service {
    //全局变量,主要为了做Looper消息的停止,做Handler的回收。
    private volatile Looper mServiceLooper;
    //ServiceHander为Handler的子类,切换线程的类。
    private volatile ServiceHandler mServiceHandler;
    //服务的名称
    private String mName;
    //是否重新投递,用来处理服务被异常杀死,后重启后消息重发逻辑,true重发,false不重发,默认不重发。
    private boolean mRedelivery;

    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);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //此类主要是为了创建Handler的Looper,具体实现请读者自己读源码,源码实现很简单。
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        //这里在线程start()后不会拿到null的looper的,由于这里getLooper时,如果mLooper没有初始化时,wait()等待了一下,详情请阅读源码。
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
  
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        //退出looper
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    //需要子类实现。
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈德山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值