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。