对比: IntentService是Service的子类,和Service不同的是,IntentService内部已经实现绑定好一个工作线程,因此,在IntentService中可以直接执行耗时操作,这样就省下了我们要在Service中人为创建线程来处理耗时操作的时间,减轻了工作量。
IntentService是可以处理异步请求的Service。每次所有的请求都会被放置在Looper管理的消息队列中。当消息队列不为空的时候,会依次取出请求并交给工作线程处理,直至所有的请求被处理完成。线程结束后将会自动停止。需要注意的是IntentService每次只能有一个任务被工作线程执行(唯一)在工作。下面我们直接分析相关源码:
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) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
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;
}
protected abstract void onHandleIntent(Intent intent);
}
IntentService是由Looper,Handler,Service共同组合而成。
1、IntentService在创建时执行onCreate()。在创建HandlerThread线程后,获取当前线程的Looper对象来初始化mServiceLooper,接着创建mServiceHandler。在此过程中工作线程和mServiceHandler进行了绑定。
2、启动IntentService时,产生一条Message(携带startId和Intent),并将该Message发送到MessageQueue中。然后,Looper一旦发现该Message,则将该Message交给mServiceHandler中的handleMessage处理。
3、接着会调用onHandleIntent()来处理。这个方法是抽象方法,需要我们在子类中重写该方法实现相关的处理逻辑。任务一旦完成就会调用stopSelf()来结束指定的工作线程。值得注意的是onHandleIntent()是运行在工作线程当中的。
4、当所有的工作完成之后,执行onDestory()方法,其中通过调用mServiceLooper.quit()来在服务结束时停止Looper。
总结:
IntentService是基于消息队列(MessageQueue)的服务,,每次启动服务并不会马上处理工作,而是首先创建对应的Looper、Handler。任务的执行顺序即queue队列Message的顺序(排队执行)。任务一旦完成,将会自行停止。因此其使用范围多在以下几种情况:
更新客户端版本
需要在后台执行单任务
多个允许异步执行的后台任务(无前后顺序和时间顺序的要求)
优缺点:
使用方便,避开了我们自己需要Service中创建线程。
由于只有一个工作线程,所有任务的执行都需要排队,因为不适合对任务并发的情况。
简单测试:
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("IntentService", "ui thread name:"+Thread.currentThread().getName());
for(int i=0;i<10;i++)
startService(new Intent(this, AsyncService.class));
}
}
public class AsyncService extends IntentService {
public AsyncService() {
super("async");
}
@Override
protected void onHandleIntent(Intent intent) {
try {
Log.d("IntentService", "work thread name:"+Thread.currentThread().getName());
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果:
1、耗时操作未产生ANR
2、输出的Log日志为: