不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的。所以,如果你的Service将要运行非常耗时或者可能被阻塞的操作时,你的应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,你应该在Service中重新启动一个新的线程来进行这些操作。现有两种方法共大家参考:
① 直接在Service的onStartCommand()方法中重启一个线程来执行,如:
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- MyServiceActivity.updateLog(TAG + " ----> onStartCommand()");
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 此处进行耗时的操作,这里只是简单地让线程睡眠了1s
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- return START_STICKY;
- }
② Android SDK 中为我们提供了一个现成的Service类来实现这个功能,它就是IntentService,它主要负责以下几个方面:
- Creates a default worker thread that executes all intents delivered to
onStartCommand()
separate from your application's main thread.
生成一个默认的且与主线程互相独立的工作者线程来执行所有传送至 onStartCommand() 方法的Intetnt
- Creates a work queue that passes one intent at a time to your
onHandleIntent()
implementation, so you never have to worry about multi-threading.
生成一个工作队列来传送Intent对象给你的onHandleIntent()方法,同一时刻只传送一个Intent对象,这样一来,你就不必担心多线程的问题。
- Stops the service after all start requests have been handled, so you never have to call
stopSelf()
.
在所有的请求(Intent)都被执行完以后会自动停止服务,所以,你不需要自己去调用stopSelf()方法来停止该服务
- Provides default implementation of
onBind()
that returns null.
提供了一个onBind()方法的默认实现,它返回null
- Provides a default implementation of
onStartCommand()
that sends the intent to the work queue and then to youronHandleIntent()
implementation
提供了一个onStartCommand()方法的默认实现,它将Intent先传送至工作队列,然后从工作队列中每次取出一个传送至onHandleIntent()方法,在该方法中对Intent对相应的处理.
IntentService 执行完onHandleIntent()中的任务后会自动执行onDestroy(); 下次再调用该IntentService,会重新调用onCreate()->onStartCommand()->onHandleIntent()生命周期。
IntentService有7个方法,其中最重要的是onHandleIntent(),在这里调用worker线程来处理工作,每次只处理一个intent,像上面描述的,如果有多个,它会顺序处理,直到最后一个处理完毕,然后关闭自己。一点都不用我们操心,多好。
再介绍另一个很有意思的方法,setIntentRedelivery()。从字面理解是设置intent重投递。如果设置为true,onStartCommand(Intent, int, int)将会返回START_REDELIVER_INTENT,如果onHandleIntent(Intent)返回之前进程死掉了,那么进程将会重新启动,intent重新投递,如果有大量的intent投递了,那么只保证最近的intent会被重投递。这个机制也很好,大家可以尝试着用。