什么是 IntentService

service 默认也运行在 UI 线程,所以里面不能直接做耗时操作,要做耗时操作还得开启子线程来做。

IntentService 就是一个 Service, 只不过里面给你默认开启了一个子线程来处理所有的 intent 请求。

而多次调用 startService 时所有请求都会放到这个子线程中一个接一个的按顺序执行,等所有的请求都处理完毕后 service 会自动销毁。

一句话描述就是用一个子线程来依次处理各个请求,请求按顺序一个接一个执行。按顺序执行是通过 Looper 队列实现的。

 看看源码就清晰了

/**
 * 这段注释应该多读几遍
 * IntentService is a base class for Service that handle asynchronous
 * requests (expressed as Intent) on demand.  Clients send requests
 * through startService(Intent)} calls; the
 * service is started as needed, handles each Intent in turn using a worker
 * thread, and stops itself when it runs out of work.
 *
 * All requests are handled on a single worker thread -- they may take as
 * long as necessary (and will not block the application's main loop), but
 * only one request will be processed at a time.
 */
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) {
            // handleMessage 还是在 onCreate 中启动的子线程中执行,因为 Looper 在哪个线程 handler 就在哪个线程执行
            // 消息队列保证了所有请求按顺序执行
            onHandleIntent((Intent)msg.obj);

            // 这里貌似停止了服务, 其实不是只有当 startId 等于最后一次启动服务时的 startId 时服务才会销毁
            stopSelf(msg.arg1);
        }
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        // onCreate 时启动一个带有 Looper 的子线程
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

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

    @Override
    public void onStart(Intent intent, int startId) {
        // 每次 onStart 时都发送一个消息到消息队列中等待执行
        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;
    }

    /**
     * 这段注释也应该多读几遍
     * This method is invoked on the worker thread with a request to process.
     * Only one Intent is processed at a time, but the processing happens on a
     * worker thread that runs independently from other application logic.
     * So, if this code takes a long time, it will hold up other requests to
     * the same IntentService, but it will not hold up anything else.
     * When all requests have been handled, the IntentService stops itself,
     * so you should not call stopSelf.
     */
    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);
}

看似简单其实里面东西挺多,发现网上好多人理解有误区,有人认为是每 start 一次都开启一个 worker 线程, 其实不是如果 service 还没有销毁多次调用

都只有一个线程来按顺序来处理请求。

 

posted @ 2016-04-07 15:08  LeslieFang  阅读(298)  评论(0编辑  收藏  举报