我们在使用 Service 时总会创建一个线程来执行任务,而不是直接在 Service中执行。这是因为 Service 中的程序仍然运行于主线程中,当执行一项耗时操作时,不新建一个线程的话很容易导致ANR错误.
IntentService 在 onCreate()中通过 HandlerThread 单独开启一个线程来处理所有Intent 请求对象所对应的任务,这样以免请求处理阻塞主线程。执行完一个 Intent 请求对象所对应的工作之后,如果没有新的 Intent 请求到达,就自动停止Service;否则执行下一个Intent 请求所对应的任务,直至最后执行完队列的所有命令,服务也随即停止并被销毁。所以如果使用 IntentService,用户并不需要主动使用 stopService()或者在lntentService 中使用 stopSelf()来停止。
IntentService原理
public abstract class IntentService extends Service {
public void onCreate() {
super.onCreate();
//创建了一个HandlerThread ,然后启动线程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//获取HandlerThread中的Looper与ServiceHandler进行绑定
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
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);
}
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
//将intent内容取出封装成消息
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;
}
protected abstract void onHandleIntent(@Nullable Intent intent);
public final void stopSelf() {
//stopSelf()调用的是stopSelf(int startId),只不过startId为-1而已
stopSelf(-1);
}
//startId是service的一个生命周期:onStartCommand(@Nullable Intent intent, int flags, int startId)中最后的一个参数,当多次调用startService来启动同一个service时,只有第一次会执行onCreate,然后会多次调用onStartCommand,如果你去打印log的话,你会发现尽管onCreate只执行一次,但是每次的startId却是不同的,且都大于0。 而stopSelf(int startId)中的startId与onStartCommand中的startId是一一对应的关系,所以,当我们调用stopSelf(int startId)时,系统会检测是否还有其它的startId存在,有的话就不销毁当前service,没有的话则销毁。而如果我们调用的是stopSelf(),那么无论是否还存在其它的startId,都会立即销毁当前service。这就是stopSelf()和stopSelf(int startId)两个方法的区别!
public final void stopSelf(int startId) {
}
}
网友评论