它是Service的子类,与普通Service相比,它具有如下优点:内部维护了一个线程,因此可以直接在onHandleIntent()方法中访问网络,而不需要再开线程;会将所有的启动该Service的Intent对象存储进来,然后依次执行,并且在执行完毕后,会调用stopSelf(),不需要自己处理。重写了onBind(),并返回null。
它的缺点也在于,当我们要绑定服务时,不能使用该类。
因此,当只需要Service去在后台联网获取数据时,直接继承IntentService,然后在onHandleIntent中处理联网逻辑即可。
public abstract class IntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; //首先定义了一个Handler的子类 private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj);//当handler接收到消息时,会调用onHandleIntent(),这也是唯一要重写的方法 stopSelf(msg.arg1);//请求处理完成后,自己停止 } } /** * @param name Used to name the worker thread。用来为当前的工作线程命名 */ public IntentService(String name) { super(); mName = name; } /** * 它影响onStartCommand()的返回值 */ public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } /* * 在TA中创建一个Handler对象,因此当TA中有新消息时,便调用Handler的hanldMessage()。 * 并且由于handler是创建在子线程中的,所以hanldMessage()和onHandleIntent运行在子线程中。 */ public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start();//当前的Service被创建时就启动了一个新的线程,记为TA mServiceLooper = thread.getLooper();//得到TA中的Looper对象 mServiceHandler = new ServiceHandler(mServiceLooper); } // 从这里可以看出,所有启动该Service的Intent对象都将存储在MessageQueue中。 public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg);//Service一开始,便会往MessageQueue中发送消息,从而会执行onHandleIntent } /** * You should not override this method for your IntentService. Instead, * override {@link #onHandleIntent}, which the system calls when the IntentService * receives a start request. * @see android.app.Service#onStartCommand */ @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() {//服务销毁时,也就结束Looper的loop mServiceLooper.quit(); } /** * Unless you provide binding for your service, you don't need to implement this * method, because the default implementation returns null. * @see android.app.Service#onBind */ @Override public IBinder onBind(Intent intent) { return null; } /** * 这个方法是我们唯一要重写的,用来处理联网逻辑的地方。 * This method is invoked on the worker thread with a request to process. * Only one Intent is processed at a time, but the processing happens on a * worker thread that runs independently from other application logic. * So, if this code takes a long time, it will hold up other requests to * the same IntentService, but it will not hold up anything else. * When all requests have been handled, the IntentService stops itself, * so you should not call {@link #stopSelf}. * * @param intent The value passed to {@link * android.content.Context#startService(Intent)}. */ protected abstract void onHandleIntent(Intent intent); }
Service的生命周期中有onStartCommand(Intent , int , int )方法,它会调用Service.onStart(),只不过后者已经过时,所以建议重写onStartCommand()。
当组件通过startService()启动Service时,系统会自动调用onStartCommand()。因此在IntentService中,每一个启动当前Service的Intent都会被存储到MessageQueue中。并且每一次调用onStartCommand()传入其中的startId都会不同。
服务的类型由onStartCommand()的返回值决定。常用的类型有:START_NOT_STICKY,START_STICKY和START_REDELIVER_INTENT。把返回START_REDELIVER_INTENT和START_NOT_STICKY的服务称为non-sticky服务(IntentService就属性该种服务),返回START_STICKY称为sticky服务。
对于non-sticky服务来说,会在服务认为自己已完成任务时停止。而sticky却会一直运行下去,直到外部某组件调用了stopService()为止。
如果系统需要在服务完成任务之前关闭它,START_NOT_STICKY会被关闭,而START_REDELIVER_INTENT则会在可用资源不再吃紧时,尝试再次启动。
对于IntentService来说,如果想改变它的onStartComment()返回值,只需要调用setIntentRedelivery()。
startService:启动的服务与当前的activity没有关系,当前的activity结束后该服务仍旧可以单独存在。并且Service的生命周期会经过onCreate(),onStartCommand()再到onDestroy()。
如果调用startService()时服务已经创建,那么不会再次调用onCreate(),只会重复调用onStartCommand()。如果服务不存在,那么会首先调用onCreate(),再调用onStartCommand()。
采用startService()启动的服务,只能通过stopService()来停止,并且在停止时会调用onDestory()。此时并不能通过unbindService()进行停止,否则会报IllegalArgumentException异常。
启动的Service与当前的activity绑定在一起,activity退出时(调用onDestory()),Service也直接结束。此时service的生命周期为:onCreate(),onBind(),onUnbind(),onDestory()。
如果调用bindService()时服务已经存在,那么onBind()与onCreate()都不会被再次调用;如果服务不存在,就会依次调用onCreate()与onBind()。
通过bindService()启动的服务可以通过unbindService()结束,此时会依次执行onUnbindService()与onDestory()。
也可以通过stopService()进行结束,此时不会调用onUnbindService(),会直接调用onDestory()。