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