浅谈IntentService

前言:这次我们来看下安卓为我们封装的IntentService,它有以下特点:


  • 它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类
  • 它可以用于在后台执行耗时的异步任务,当任务完成后会自动停止
  • 它拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务
  • 它内部通过HandlerThread和Handler实现异步操作
  • 创建IntentService时,只需实现onHandleIntent和构造方法,onHandleIntent为异步方法,可以执行耗时操作

一、IntentService的常规使用套路


public class MyIntentService extends IntentService {
    public MyIntentService(){
        super("MyIntentService");
    }
    /**
     * 实现异步任务的方法
     * @param intent Activity传递过来的Intent,数据封装在intent中
     */
    @Override
    protected void onHandleIntent(Intent intent) {
    }
}

二、IntentService源码解析


public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;

    private volatile ServiceHandler mServiceHandler;
    private String mName;
    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();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

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

    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);
}

先看看构造方法

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

这里是传入IntentService的名称,没什么其他操作,我们继续看

 @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

onCreate()方法调用了HandlerThread,并且start了它,并把HandlerThread的Looper对象传给了mServiceLooper这个Looper对象;并且创建了一个ServiceHandler类,传入mServiceLooper进去;所以我们要继续看看ServiceHandler这个类怎么定义的

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

我们发现ServiceHandler是继承Handler的,通过这个类来实现异步操作任务,重写handleMessage方法,里面调用了onHandleIntent方法,传入了msg.obj,说明具体UI操作在onHandleIntent方法里面定义,我们先看看这个方法怎么定义的

    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);

这个onHandleIntent是一个抽象方法,要我们具体去实现,那么消息从哪来发送呢?别忘了IntentService类继承Service,开启服务会调用onStartCommand方法,我们看下这个方法

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

我们接着看看onStart方法

@Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

我们发现在开启服务时,最终会调用onStart里的Message类发送消息,进行异步操作,ServiceHandler接收Message类发送的消息后,在onHandleIntent让用户自行实现具体UI操作,实现异步任务的完成。

最后我们看看IntentService怎么自动结束Service服务,我们看看之前没有看的stopSelf(msg.arg1)方法。这里采用stopSelf(int startId)而不是stopSelf()来停止服务,是因为stopSelf()会立即停止服务,而stopSelf(int startId)会等待所有消息都处理完后才终止服务。

猜你喜欢

转载自blog.csdn.net/weixin_38364803/article/details/80383603