我们知道Service是运行在主线程的,主线程中不能进行耗时操作,否则会发生ANR。Service中的发生ANR的超时时间是20s。
有时候我们需要应用在后台默默做一些任务,例如上传文件等。如果我们采用Service,则需要我们自己手动开启新的线程。如果我们不想 自己开启线程怎么办,IntentService就出现了。
基本使用
public class TestService extends IntentService {
public YourUploadService() {
super("TestService");
}
@Override
protected void onHandleIntent(Intent intent) {
//耗时操作
}
}
使用IntentService需要我们继承IntentService,并重写onHandleIntent方法,在onHandleIntent中进行耗时操作。
源码分析
IntentService的源码比较简单,这里就直接全部贴出
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
//子线程的Handler
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;
}
// 设置onStartComand的返回策略
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");//创建一个HandlerThread
thread.start();
mServiceLooper = thread.getLooper();//获取子线程的Looepr
mServiceHandler = new ServiceHandler(mServiceLooper);//创建ServiceHandler,子线程的Handler
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);//向子线程的Handler的发送消息,进行任务处理
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;//START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。START_NOT_STICKY:如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
总结
我们可以看到IntentService本质是一个Service,继承了Service。与Service的区别是内部通过维护了一个HandlerThread创建的线程,并与Handler搭配使用,达到在子线程中处理任务的目的。