Android Service 与 IntentService

之前只知道Service 而 不知道IntentService,一直是用 Service来处理后台耗时操作。

先看Service:

官方提示:

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.

大致意思:

Service不是一个单独的线程,所以我们应该避免在Service里面进行耗时的操作,耗时的操作应该另开一个新线程进行处理。


在处理耗时的工作时。IntentService就比较具有优势:

IntentService是Service的子类。

IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,在适当的时候会停止自己(一般在工作完成的时候). 所有的请求的处理都在一个工作线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。

public abstract class IntentService extends Service { 
	private volatile Looper mServiceLooper; 
	private volatile ServiceHandler mServiceHandler; //一个Handler封装了Looper对象 

	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,是依附在一個 non-UI thread 的 Looper 上。Looper是 Android UI 在处理各式讯息时,最重要的元件之一。而 ServiceHandler 构造中所传入的 Looper ,是在 onCreate() 中建立的。

    @Override 
    public void onCreate() { //这里重写父类Service的创建,主要是构造一个线程 
        super.onCreate(); 
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 
        thread.start();
        mServiceLooper = thread.getLooper(); 
        mServiceHandler = new ServiceHandler(mServiceLooper); 
    }

如上,
mServiceLooper 就是thread线程的Looper,这个thread就是一个HandlerThread,是一个non-UI thread。

所以现在这个Service,带有message loop(mServiceLooper)的non-UI thread(mServiceHandler)一直在后台运行,监看是否有任何传入的message。

每当调用startService(new Intet(this,MyIntentService.class))启动IntentService时,其实就是传递一个 message到mServiceHandler上。

    @Override
    public void onStart(Intent intent, int startId) {  //Android 2.0以前的Service启动参数控制 
        Message msg = mServiceHandler.obtainMessage(); 
        msg.arg1 = startId; 
        msg.obj = intent; 
        mServiceHandler.sendMessage(msg); 
    }
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { //Android 2.0以后的服务启动参数 
        onStart(intent, startId); 
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 
    }
我們知道这个 message 最终会由 Handler.handleMessage() 來处理。由于整个 mServiceHandler 是在 non-UI thread 中执行。当它在 handleMessage() 中调用你的 onHandleIntent() 时,你的 onHandleIntent() 自然也是在 non-UI thread 中执行。
    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); 
        } 
    }

onHandleIntent()执行结束后,调用 stopSelf(int)结束本身。

如果你调用 startService()多次,每一次的调用都会被转成一个message并放在mServiceLooper的message queue中,等待被处理。一个message对应的工作完成后才会继续下一个message对应的工作,所以这些队列中的message对应的工作不是并行,而是循序先后执行。

当所有的message处理完成后,就结束Service。

    @Override 
    public void onDestroy() { //服务摧毁的时候Looper一定要释放掉,这点很重要。 
        mServiceLooper.quit(); 
    }
在onDestory()中,唯一要做的事就是将mServiceLooper停下来。

你可能感兴趣的:(Android Service 与 IntentService)