IntentSerivce实现原理

1、Service的作用
Service存的理由是接手复杂耗时的计算任务,将其与UI部分隔离。不过,Service运行在主线程中,所以需要在其中单独创建额外后台线程来处理这些任务,避免占用UI线程,导致界面无响应。

2、IntentServic的作用
首先,它是一个Service,具备Service该有的功能。
其它,它封闭了后台线程的创建、关闭操作,提供了一个简单的将操作交给Serivce操作的方法。
所以,有时候使用它会比较方便,少写一些代码。但其功能是受限的,有它所适用的场景。

3、简要理解IntentSerivce的原理
用一句话来说:就是专门创建一个自带Looper的线程,接受并处理向IntentService发过来的各种消息。

4、实现原理
1)、通过Message-Handler-Looper实现主线程和后台线程的通信
要注意的是:在后台线程中构造Looper,然后不停的接收消息处理; 然后主线程向其发送消息。而不是常见的在后台线程中向主线程发送消息,刷新UI这种方式。

2)、带Looper的HandlerThread(工作线程)
HandlerThread是一个线程,继承自Thread。
public class  HandlerThread  extends  Thread {
该线程唯一要做的事情就是创建Looper,然后进入消息循环,不停的处理接收到的消息。
@Override
public void  run() {
    mTid = Process. myTid() ;
    Looper. prepare() ;
    synchronized ( this) {
        mLooper = Looper. myLooper() ;
        notifyAll() ;
    }
    Process. setThreadPriority( mPriority) ;
    onLooperPrepared() ;
    Looper. loop() ;
    mTid = - 1 ;
}
然后在IntentService中创建该线程并运行。
HandlerThread thread =  new HandlerThread( "IntentService[" mName "]") ;
thread.start() ;
3)、一个可向HandlerThread发消息的Handler
通常情况下,创建Handler时不指定Looper,则默认为将通过该Handler将消息发送至主线程的消息循环处理。然而,现在需要向HandlerThread发消息。所以,需要指定Looper。
mServiceLooper = thread.getLooper();
mServiceHandler new ServiceHandler(mServiceLooper);
4)、ServiceHandler的实现
创建Handler时,必须要实现onHandlerIntent(),以便在其中进行消息处理。ServiceHandler中也是如此,不过在其中的消息处理非常简单,就是处理下消息,然后调用Service.stopSelf()停止IntentSerivce。
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) ;
    }
}
5)、onHandlerIntent具体做什么
这个交给具体的应用,其被定义为抽像方法。
所以, 这就决定了在使用IntentSerivce时,必须从它继承,然后再实现onHandleIntent()方法。在onHandleIntent()中运行的代码全部在HandlerThread中运行
protected abstract void onHandleIntent(Intent intent);
6)、如何发消息给ServiceHandler
通过多次调用startSerive(intent),可启动Service。如果Service没有启动,则会先创建,再启动,再调用onStartCommand(intent); 如果已经启动了,则会直接调用onStartCommand()。在onStartCommand()中会调用onStart(),在其中会向ServiceHandler发送消息。
public void  onStart(Intent intent , int startId) {
    Message msg =  mServiceHandler.obtainMessage() ;
    msg. arg1 = startId ;
    msg. obj = intent ;
    mServiceHandler.sendMessage(msg) ;
}
为什么不直接在onStartCommand()发送消息。查看Service源码可看到,onStart已经被废弃,可能是想兼容以前的代码吧。
7)、IntentService会在每次接受到消息时启动,处理完后结束自己么?
不会。多次调用startSerive(intent),并不会导致Service多次启动,而只会多次调用onStartCommand(intent),所有的Intent()都会通过mSerivceHander发送至HandlerThread的消息队列。
每次onHandlerIntent()处理完消息后,虽然会调用
stopSelf(msg. arg1) ;
但是只有在所有的请求全部处理完毕后,才会结束当前服务。

8)、IntentSerivce可以Bind吗
为什么不可以?Serivce可以同时bind和start。

你可能感兴趣的:(Android)