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 还没有销毁多次调用
都只有一个线程来按顺序来处理请求。