IntentService

2022-08-29  本文已影响0人  内卷程序员

我们在使用 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) {

  }
}
上一篇下一篇

猜你喜欢

热点阅读