IntentService
我们直接分析 IntentService 的源码,如下:
public abstract class IntentService extends Service {
    // Looper 对象
    private volatile Looper mServiceLooper;
    // Handler 对象
    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);
            // 根据 startId 来销毁自身,如果多次启动服务,最后一次才会销毁成功并回调 onDestroy
            stopSelf(msg.arg1);
        }
    }
    public IntentService(String name) {
        super();
        // 设置线程名称
        mName = name;
    }
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        // 创建 HandlerThread
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        // 启动
        thread.start();
        mServiceLooper = thread.getLooper();
        // 创建 Handler
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        // 把相应信息封装成 Message 对象
        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 方法
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
    @Override
    public void onDestroy() {
        // 退出循环,即销毁线程,回收资源
        mServiceLooper.quit();
    }
    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        // 直接返回 Null
        return null;
    }
    // 抽象方法,子类覆写来执行具体的业务逻辑
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}
实现逻辑分析:
- 在 - onCreate()方法中使用了一个- HandlerThread来维护线程,传入- HandlerThread内部维护的- Looper来创建- ServiceHandler。
- 在 - onStart()方法中将- Intent和- startId作为参数封装进了- Message,并发送到- ServiceHandler来处理。
- 在 - onStartCommand()方法直接调用第二步的- onStart()方法。
- 在 - Handler的- handleMessage()回调中会调用抽象方法- onHandleIntent(),执行完之后,会调用- stopSelf(startId)方法来销毁自身,每次启动服务时- startId都会不一样,只有当最近的- onStart()的- startId等于- stopSelf(startId)时才会销毁成功并回调- onDestroy()方法。比如说,如果只启动一次服务,第一次启动时,- startId为- 1,那么执行- stopSelf(startId)时的- startId也为 1 ,则销毁成功。如果启动了两次服务,假设第二次启动时- startId为- 2,当处理第一次的逻辑时执行到- stopSelf(startId),此时的- startId为上一次的- startId,即为- 1,则销毁不成功,继续处理第二次的处理逻辑,处理完才会销毁成功。也就是说,多次启动服务时,会顺序处理每次的请求,全部处理完后,才销毁服务 。
- 在 - onDestroy()中会退出循环,即销毁线程,回收资源。
IntentService 使用示例
自定义 IntentService 类:
public class TestIntentService extends IntentService {
    private static final String PARAM = "test";
    public TestIntentService() {
        super("TestIntentService");
    }
    public static void startIntentService(Context activity, String param) {
        Intent intent = new Intent(activity, TestIntentService.class);
        intent.putExtra(PARAM, param);
        activity.startService(intent);
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("TestIntentService", "onHandleIntent 线程名称" + Thread.currentThread().getName());
        if (intent.getStringExtra(PARAM).equals("first")) {
            try {
                Log.d("TestIntentService", "first start");
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            try {
                Log.d("TestIntentService", "again start");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestIntentService", "onDestroy 线程名称" + Thread.currentThread().getName());
    }
}
启动服务:
if (isReadStart) {
               TestIntentService.startIntentService(this, "again");
           } else {
               TestIntentService.startIntentService(this, "first");
               isReadStart = true;
           }
打印日志:
D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: first start
D/TestIntentService: onHandleIntent 线程名称 IntentService[TestIntentService]
D/TestIntentService: again start
D/TestIntentService: onDestroy 线程名称 main