为了创建一个service,我们需要创建一个继承自Service的类。并override一些callback方法。最重要的一些方法如下:当系统资源不足时,会强制停止service,并在用户重新回到activity时,系统对其进行恢复。如果一个service是bind到一个活动的activity上,则不容易被kill掉。假设service被声明为run in the foreground,那就几乎不会被kill掉。随着service被不断执行,它会被慢慢降低优先级,当系统资源不足时,会先stop这些优先级低的service,假设这个service被kill掉,那么会在资源足够时马上恢复它。
publicclassHelloIntentServiceextendsIntentService{/** * A constructor is required, and must call the super IntentService(String) * constructor with a name for the worker thread. */publicHelloIntentService(){super("HelloIntentService");}/** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */@OverrideprotectedvoidonHandleIntent(Intentintent){// Normally we would do some work here, like download a file.// For our sample, we just sleep for 5 seconds.longendTime=System.currentTimeMillis()+5*1000;while(System.currentTimeMillis()<endTime){synchronized(this){try{wait(endTime-System.currentTimeMillis());}catch(Exceptione){}}}}}
publicclassHelloServiceextendsService{privateLoopermServiceLooper;privateServiceHandlermServiceHandler;// Handler that receives messages from the threadprivatefinalclassServiceHandlerextendsHandler{publicServiceHandler(Looperlooper){super(looper);}@OverridepublicvoidhandleMessage(Messagemsg){// Normally we would do some work here, like download a file.// For our sample, we just sleep for 5 seconds.longendTime=System.currentTimeMillis()+5*1000;while(System.currentTimeMillis()<endTime){synchronized(this){try{wait(endTime-System.currentTimeMillis());}catch(Exceptione){}}}// Stop the service using the startId, so that we don't stop// the service in the middle of handling another jobstopSelf(msg.arg1);}}@OverridepublicvoidonCreate(){// Start up the thread running the service. Note that we create a// separate thread because the service normally runs in the process's// main thread, which we don't want to block. We also make it// background priority so CPU-intensive work will not disrupt our UI.HandlerThreadthread=newHandlerThread("ServiceStartArguments",Process.THREAD_PRIORITY_BACKGROUND);thread.start();// Get the HandlerThread's Looper and use it for our Handler mServiceLooper=thread.getLooper();mServiceHandler=newServiceHandler(mServiceLooper);}@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){Toast.makeText(this,"service starting",Toast.LENGTH_SHORT).show();// For each start request, send a message to start a job and deliver the// start ID so we know which request we're stopping when we finish the jobMessagemsg=mServiceHandler.obtainMessage();msg.arg1=startId;mServiceHandler.sendMessage(msg);// If we get killed, after returning from here, restartreturnSTART_STICKY;}@OverridepublicIBinderonBind(Intentintent){// We don't provide binding, so return nullreturnnull;}@OverridepublicvoidonDestroy(){Toast.makeText(this,"service done",Toast.LENGTH_SHORT).show();}}
START_NOT_STICKY: If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver.
START_STICKY: recreate the service and call onStartCommand(), but do not redeliver the last intent.除非系统有pending的intent,否则会丢给onstartCommand()一个null的intent。这适合于media player一类的service。(This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.)
START_REDELIVER_INTENT: recreate the service and call onStartCommand() with the last intent that was delivered to the service. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file. 适合于下载等需要立即恢复的工作。
publicclassExampleServiceextendsService{intmStartMode;// indicates how to behave if the service is killedIBindermBinder;// interface for clients that bindbooleanmAllowRebind;// indicates whether onRebind should be used@OverridepublicvoidonCreate(){// The service is being created}@OverridepublicintonStartCommand(Intentintent,intflags,intstartId){// The service is starting, due to a call to startService()returnmStartMode;}@OverridepublicIBinderonBind(Intentintent){// A client is binding to the service with bindService()returnmBinder;}@OverridepublicbooleanonUnbind(Intentintent){// All clients have unbound with unbindService()returnmAllowRebind;}@OverridepublicvoidonRebind(Intentintent){// A client is binding to the service with bindService(),// after onUnbind() has already been called}@OverridepublicvoidonDestroy(){// The service is no longer used and is being destroyed}}