您好,欢迎来到99网。
搜索
您的当前位置:首页Android_service

Android_service

来源:99网
AndroidService

原文地址:http://www.cnblogs.com/jerry-lin300/archive/2011/12/15/2288818.html 作为android四大组件之一,Services主要用作后台的、耗时操作。它没有UI。应用程序的其他组件可以启动Service,此时Service 即会在后台持续运行,即使用户切换到了其他应用程序,service也依旧运行。此外,组件可以绑定一个Service,一般和它进行交换,甚至实现进程间通信(IPC)。一般:网络传输、播放音乐、执行文件I/O,或者和内容提供者(content provider)交互,都可以放到Service中到后台来执行。

之前已经提到,Service可以被启动,也可以被绑定。不难理解,Service的两种形式:started Service和bound Service。

started:这是一种被应用的组件以调用startService()方法的方式启动的Service。这种Service,被启动后,就开始运行,即便当初启动它的组件被摧毁了,也依旧工作。通常,一个started Service执行单独的、不需向调用者返回结果的操作。当操作完成以后,服务应该结束自己。例如,通过网络上传、下载一个文件。

 bound:这是一种被应用的组件以调用bindService()方法的方式启动的service。这种Service,提供一种Client-Server的接口,来允许组件和Service进行交互:发送请求、获取结果,甚至以这种方式实现夸进程的IPC。bound Service的生命周期依赖于绑定它的组件,和绑定它的组件的生命周期一致。当绑定它的组件的生命周期结束时,bound Service的生命周期也结束。bound Service可以被多个组件绑定,此时,只有多有和它绑定的组件和它unbind之后,这个Service才被摧毁。

 混合模式:一个Service可以同时是started、bound模式,Service支持同时是started、bound的方式。

看上去Service和Thread很像,那么什么时候使用Service,什么时候使用Thread?一般,如果不需要和用户交互也需要执行的任务可以选择使用Service,如果任务只在用户交互驱动时,才工作的,而又不想在main线程中执行,可以选择使用Thread。 不管是哪种模式的Service,任何一个应用的组件都可以以一种相同的方式使用一个Service,——以Intent来启动。当然,也可以在manifest中声明为私有,阻止来自其他程序的访问。

service 基础

为了创建一个Service,必须创建一个继承自Service或者它的子类的类。在实现中,需要重载一些回调方法来处理Service生命周期的关键环节,以及为组件绑定该Service提供一种合适的机制。下面是一些在创建的类中,需要实现的最重要的回调方法:

onStartCommand():其他组件调用startService()来启动一个Service时,系统会调用这个回调函数,该函数执行过后,Service就已经被启动了,并且开始在后运行。如果你实现了这个函数,那么就必须由你来停止Service,要么调用stopSelt(),要么调用stopService()。也就是说,如果Service只是向提供绑定服务,那么就不需要实现这个方法。让其使用系统默认的实现。

 onBind():其他组件调用bindService()来绑定一个Service时,系统会调用这个回调函数。在实现这个方法(onBind())时,必须提供一个可供Client和Service通信的接口,该接口通过返回一个IBinde来传递。如果不允许service被绑定,那么这里返回null,否则必须实现这个接口。

 onCreate():系统在Service第一次被创建的时候调用该方法,它是再onStartCommand()和onBind()方法之前被调用的。如果这个Service已经在运行了,那么这个函数不会被调用。

 onDestroy():系统在一个Service不再被使用,并且准备摧毁的时候调用该方法,它是Service收到的最后一个被调用的方法。在这里可以进行一些清除工作,例如线程、注册的监听、以及接收器等等。

一个被startService()方法启动的Service,它将会一直运行,直到自己调用了stopSelf(),或者其他组件调用了stopService()。

一个被bindService()犯法启动的Service,它的生命周期和绑定在它上面的组件一样。一旦所有绑定其的client都解绑定了,系统就会摧毁这个Service。

android系统只有在内存不足时,并且必须为拥有焦点的activity回收资源时,强制停止一个Service。如果一个service绑定到了一个拥有焦点的activity上,那么它被杀死的几率比普通的更低。而如果一个Service被声明为在前台运行,那它几乎不可能被杀死。然而如果,一个仅仅只是长期运行的long-running Service,系统将它的位置设置地比后台任务低好几倍,并且这种Service很容易被杀死,你必须优雅地设计这种Service,以便处理其被系统重新启动的情况。

要使用一个service,首先需要类似activity那样在manifest中声明service。如:

...

... 复制代码

如果不希望被其他应用使用,则只须不声明 intent filter.如何这么做,那只能显示地调用Service类名。此外,可以设置android:exported,为false,来设置Service为你的应用所私有的。

创建一个started service

started service是一个由其它组件通过调用startService()方法启动的Service,并且这种方式将导致系统调用onStartCommand()方法(如果目标机是1.6或者1.6以前的话,则要以onStart()。2.0以后onStart()被废弃)。

其它组件通过Intent指定Service,并且包含一些供Service使用的数据。Service通过onStartCommand()接收Intent。

由于started Service的生命周期于启动它的组件,所以在其任务完成时,需要调用stopself()或者其它组件调用stopService()。

需要注意的是,Service是运行在声明它的应用程序的进程中,并且默认运行在主线程中。所以如果Service执行一些密集的、阻塞型的操作,它将会是activity和用户的交互变慢,为了避免影响应用程序的性能,应该在Service中启动一个新的线程。

有两个类可以用来扩展、继承以创建一个新的Service:

Service:这是所有Service的基类。当使用这个类时,在Service中创建一个线程来实现Service的所有工作,是非常重要的(因为之前已经提到,默认情况下,Service运行在程序的主线程中)。

 IntentService:这是Service的一个子类,它使用一个工作线程来处理所有的启动请求,每次执行一个请求。如果你不需要一个Service同时处理多个请求,这是一个最好的选择。使用这这个类时,所有需要做的,仅仅只是实现onHandleIntent(),来处理请求。

继承、扩展IntentService类

IntentService做了以下工作:

 创建一个默认的工作线程,来处理从应用程序主线程投递到onStartCommand()的Intent。

 创建一个队列,它每次向onHandleIntent()传递一个Intent,这样就不需要关心多线程的同步问题。

 在所有启动请求都被处理之后,自动停止Service,这样开发人员就不需要调用stopSelf()。

 

提供了默认的onBind()实现,它返回null。

提供了默认的onStartCommand()实现,它将intent发送到工作队列中,然后工作队列再讲intent发送到onHandleIntent()。

以上所有都表明,开发人员只需要实现onHandleIntent()方法,例如:

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. */ @Override

protectedvoidonHandleIntent(Intent intent){

// 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()wait(endTime -System.currentTimeMillis()); }catch(Exception e){ } } } } } 复制代码

例中所有需要开发者做的就是,实现Service的构造函数和onHandleIntent()。 如果你决定要覆盖其他的回调函数,那么要保证调用超类的中的实现。例如onStartCommand()必须返回默认的实现:

@Override

publicintonStartCommand(Intent intent,intflags,intstartId){

Toast.makeText(this,\"service starting\returnsuper.onStartCommand(intent,flags,startId); } 复制代码

继承、扩展Service类

当需要Service实现多线程并发的请求时,应该从Service类扩展,来处理每一个Intent。例如:

publicclassHelloServiceextendsService{ privateLoopermServiceLooper;

privateServiceHandlermServiceHandler;

// Handler that receives messages from the thread privatefinalclassServiceHandlerextendsHandler{ publicServiceHandler(Looperlooper){ super(looper); }

@Override

publicvoidhandleMessage(Message msg){

// 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()wait(endTime -System.currentTimeMillis()); }catch(Exception e){ } } }

// Stop the service using the startId, so that we don't stop // the service in the middle of handling another job stopSelf(msg.arg1); } }

@Override

publicvoidonCreate(){

// 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. HandlerThread thread =newHandlerThread(\"ServiceStartArguments\Process.THREAD_PRIORITY_BACKGROUND); thread.start();

// Get the HandlerThread'sLooper and use it for our Handler mServiceLooper = thread.getLooper();

mServiceHandler =newServiceHandler(mServiceLooper); }

@Override

publicintonStartCommand(Intent intent,intflags,intstartId){

Toast.makeText(this,\"service starting\

// 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 job Message msg = mServiceHandler.obtainMessage();

msg.arg1 = startId;

mServiceHandler.sendMessage(msg);

// If we get killed, after returning from here, restart return START_STICKY; }

@Override

publicIBinderonBind(Intent intent){

// We don't provide binding, so return null returnnull; }

@Override

publicvoidonDestroy(){

Toast.makeText(this,\"service done\ } } 复制代码

这个例子中,为每一个启动请求,都启动一个工作线程来完成这项共工作,每次只处理一个请求。由于开发者实现了onStartCommand(),所以可以并发的执行多个请求。如果有需求,可以为每个请求启动一个线程,然后使它们正确地运行。

onStartCommand()必须返回一个整数,这个整数,告诉系统,如何继续这个Service,当系统杀死这个Service的时候。onStartCommand()的返回值,必须是以下几个:

START_NOT_STICKY,如果系统在onStartCommand()之后杀死了Service,除非有待投递的Intent,否则不要在重新创建Service。这是一个安全的选项,使得能够避免在不需要的时候运行Service,并且能够简单地重启那些未完成的工作。

 START_STICKY,重启Service,并且重新调用onStartCommand(),但是不要再次投送最后一个Intent。取而代之的是,系统调用onStartCommand(),并且,除非Service中还有其它待投递的Intent,否则向它传递null Intent。这种情形适合Media players——未在执行命令的,并且无限期的运行、等待工作的媒体播放器。

 START_REDELIVER_INTENT,重新创建Service,并且传递最近的一个Intent。其它待投递的Intent有序的跟着被投递。这种情形适合那些积极的执行那种必须马上恢复工作的Service,例如下载文件。

启动一个Service

activity或者应用程序的其他组件,可以通过向startSerive()传递一个Intent来启动一个Service,系统调用Service的回调函数onStartCommand(),并且向其传递这个Intent。例如:

Intent intent =newIntent(this,HelloService.class); startService(intent);

如果该Intent还未运行,那么系统会先调用onCreate(),然后调用onStartCommand()。

如果Service不提供绑定。通过startService()投递Intent是应用组件和Service唯一的通信方式。然而,如果你希望Service发回结果,那么启动该Service的Client可以为广播(getBroadcast())创建一个待定的Intent(PendingIntent),并且随Intent一起通过startService()投递,然后Service可以使用这个广播来返回结果。

多个请求要启动Service,导致了系统对应地调用onStartCommand(),然而,想要停止一个Service,只需要一个请求(stopSelf()或者stopService())。

停止一个Service

一个Started的Service,必须自己管理生命周期,因为,除非系统为了回收内存,否则不会停止或者摧毁这样的Service,并且即便因为回收内存而摧毁了这样的Service,也会在onStartCommand()返回后继续运行。所以必须调用stopSelf()或者被其他组件调用stopService(),来终止一个Service。

一旦调用了stopSelf()或者stopService(),系统将在尽可能快的时间里终止Service。 然而,如果你的Service正在处理多个请求,那么就不能终止请求,因为有可能接收到了多个启动请求(在第一个请求的结尾结束,可能导致终止第二个请求)。为了避免这种情况,可以使用stopSelf(int),来保证停止Service的请求是基于最近的请求。这是因为,当调用stopSelf(int)时,你传递了对应的要停止的请求的启动请求的ID(statedID被投递到onStartCommand()),然后如果在你调用stopSelf(int)之前收到了一个新的请求,那么这两个ID将不会匹配,此时Service就不会被停止。

创建一个Bound Service

一个Bound Service允许应用程序的其它组件调用bindService(),以创建一个长期的存在的连接(并且一般不允许组件通过调用startService()来启动它)。

当你需要同过IPC让应用程序的组件(activity和其它组件)和Service进行交互的时候,或者想要将应用中的一些功能暴露给其它应用程序的时候,应该创建一个bound service。为了创建Bound Service,必须实现onBind()回调方法,它返回一个IBinder——它定义了和Service交互的接口。其它应用的组件可以调用bindService()来接收这个接口,并且开始调用在Service上的方法。这种Service只在应用程序的组件绑定它的时候才存活。所以当没有组件和Service绑定的时候,系统将摧毁这个Service。

为了创建一个Bound Service,必须首先定义指定Client和Service如何交互、通信的接口。Client和Service直接的接口必须是一个IBinder,也就是Service中onBind()回调必须要返回的IBinder。Client接收到IBinder之后,就可以和Service交互了。 有多个Client可以绑定到一个Service上,Client调用unbindService()来解绑定,如之前提到过的,一点一个Service没有Client绑定到它上面时,系统将会摧毁它。

我们知道,在创建一个Bound Service时,必须一个IBinder接口以供Client和Service交互、通信。有三种方式可以用来定义这样的一个接口:

扩展Binder类(Extending the Binder class):如果Service是你的程序所私有的,并且和Client允许在同一个进程中,你应该通过扩展Binder类来创建接口,并且从onBinde()返回它的实例。Client接收到以后,通过它直接访问Binder中、或者Service中的Public方法。当服务是你的程序私有的时候,这是首选的一项技术。不能以这个方式创建接口的唯一理由是,Service要被其他程序所用,或者需要跨进程使用。

 使用一个Messenger(Using a Messenger):如果需要接口能够在跨进程间使用,可以以一个Messenger创建接口,这种方式,Service定义一个Handler来响应各种不同的Message对象。这个Handler是Messager和Client共享一个IBinder的基础,它允许Client使用Message对象向Service发送命令。并且Client也可以定义一个Messenger,这样Service可以向Client发送Messages。这是一种简单的IPC,因为Messenger队列要求是个单线程的,这样就不许要为线程安全而设计Service。

 使用AIDL(Using AID):AIDL(ANDROID INTERFACE DEFINITION LANGUAGE)执行所有工作——将对象分解成系统能理解的原语,并且使它们能够跨进程执行。使用Messenger的方式,实际是就是基于AIDL的。和Messenger方式不同的是,Messenger方式,在一个单独的线程中创建所有请求的队列,所以这样的Service每次只能接收一个请求。而如果需要Service并发地处理请求,那就可以直接使用AIDL来实现,此时,Service必须具备多线程能力,并且要线程安全的。

为了能够直接使用AIDL,必须创建一个.adil文件,它定义了程序的接口。android sdk tool用这个文件来生成抽象类——实现interface和处理IPC,然后在Service中继承、扩展它。

继承、扩展Binder类

如果Service只在本地程序工作,并且不考虑跨进程,那么就可以通过这种继承、扩展Binder类来实现,它使Client直接访问Service中Public的方法。 这种方式须遵循以下步骤:

在Service中创建一个Binder的实例:

  

包含Client可以调用的Public方法。

返回当前Service的实例——也包含Client可以调用的Public方法。 返回Service持有的其他类的的实例——也包含Client可以调用的Public方法。

 

在onBind()中返回Binder实例。

在Client侧,从onServiceConnected()回调方法中接收这个Binder,并且使用Binder包含的Service提供的方法。

publicclassLocalServiceextendsService{ // Binder given to clients

privatefinalIBindermBinder =newLocalBinder(); // Random number generator

privatefinalRandommGenerator =newRandom(); /**

* Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */

publicclassLocalBinderextendsBinder{ LocalServicegetService(){

// Return this instance of LocalService so clients can call public methods returnLocalService.this; } }

@Override

publicIBinderonBind(Intent intent){

returnmBinder; }

/** method for clients */ publicintgetRandomNumber(){ returnmGenerator.nextInt(100); } }

publicclassBindingActivityextendsActivity{ LocalServicemService; booleanmBound =false;

@Override

protectedvoidonCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); }

@Override

protectedvoidonStart(){ super.onStart(); // Bind to LocalService

Intent intent =newIntent(this,LocalService.class); bindService(intent, mConnection,Context.BIND_AUTO_CREATE); }

@Override

protectedvoidonStop(){ super.onStop();

// Unbind from the service if(mBound){

unbindService(mConnection); mBound =false; } }

/** Called when a button is clicked (the button in the layout file attaches to

* this method with the android:onClick attribute) */ publicvoidonButtonClick(View v){ if(mBound){

// Call a method from the LocalService.

// However, if this call were something that might hang, then this request should

// occur in a separate thread to avoid slowing down the activity performance.

intnum = mService.getRandomNumber();

Toast.makeText(this,\"number: \"+ num,Toast.LENGTH_SHORT).show(); } }

/** Defines callbacks for service binding, passed to bindService() */ privateServiceConnectionmConnection =newServiceConnection(){

@Override

publicvoidonServiceConnected(ComponentNameclassName, IBinder service){

// We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder binder =(LocalBinder) service; mService = binder.getService(); mBound =true; }

@Override

publicvoidonServiceDisconnected(ComponentName arg0){ mBound =false; } }; } 复制代码

使用一个Messenger

如果需要Service能够和远端进程通信,可以是哟一个Messenger提供Service的接口,这项技术允许执行IPC,而不需要用AIDL。

Service实现一个Handler——用来接收来自Client的回调。

  

这个Handler用来创建一个Messenger对象——一个Hnadler的引用。 Messenger创建一个IBinder——由onBind()返回。

Client使用IBinder来实例化Messenger(—一个Hnadler的引用),Client通过这个Messenger向Service发送Message对象。

 Service在它的Handler中接收每一个Message。

这种方式,Client以向Service投递消息替代调用Service的Public方法。

publicclassMessengerServiceextendsService{ /** Command to the service to display a message */ staticfinalint MSG_SAY_HELLO =1; /**

* Handler of incoming messages from clients. */

classIncomingHandlerextendsHandler{ @Override

publicvoidhandleMessage(Message msg){ switch(msg.what){ case MSG_SAY_HELLO:

Toast.makeText(getApplicationContext(),\"hello!\_SHORT).show(); break; default:

super.handleMessage(msg); } } } /**

* Target we publish for clients to send messages to IncomingHandler. */

finalMessengermMessenger =newMessenger(newIncomingHandler()); /**

* When binding to the service, we return an interface to our messenger

* for sending messages to the service. */ @Override

publicIBinderonBind(Intent intent){

Toast.makeText(getApplicationContext(),\"binding\how();

returnmMessenger.getBinder(); } }

publicclassActivityMessengerextendsActivity{

/** Messenger for communicating with the service. */ Messenger mService =null;

/** Flag indicating whether we have called bind on the service. */ booleanmBound; /**

* Class for interacting with the main interface of the service. */

privateServiceConnectionmConnection =newServiceConnection(){

publicvoidonServiceConnected(ComponentNameclassName,IBinder service){ // This is called when the connection with the service has been // established, giving us the object we can use to

// interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object. mService =newMessenger(service); mBound =true; }

publicvoidonServiceDisconnected(ComponentNameclassName){ // This is called when the connection with the service has been

// unexpectedly disconnected -- that is, its process crashed. mService =null; mBound =false; }

};

publicvoidsayHello(View v){ if(!mBound)return;

// Create and send a message to the service, using a supported 'what' value Message msg =Message.obtain(null,MessengerService.MSG_SAY_HELLO,0,0); try{

mService.send(msg);

}catch(RemoteException e){ e.printStackTrace(); } }

@Override

protectedvoidonCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); }

@Override

protectedvoidonStart(){ super.onStart(); // Bind to the service

bindService(newIntent(this,MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); }

@Override

protectedvoidonStop(){ super.onStop();

// Unbind from the service if(mBound){

unbindService(mConnection); mBound =false; } } }

复制代码

绑定到一个Service

应用程序的通过bindService()绑定到一个Service。Android系统调用Service的onBind(),它返回IBinder,以便Client和Service交互。

注意:只有activities、services和content providers可以绑定到一个Service,不能从broadcast receiver绑定一个service。

从Client绑定一个Service:

实现ServiceConnection:必须覆盖两个回调方法:

onServiceConnected()——系统调用这个方法来投递IBinder(从service的onBinder()方法返回)。

 onServiceDisconnected()——当Client和Service之间的连接不是期望的丢失,例如Service崩溃,或者被杀死时,android系统调用这个方法。Client解绑定时,这个函数不会被调用。

 

调用bindService()。

在系统调用onServieConnected()时,就可以开始向通过调用定义的接口,呼叫Services。

 调用unbindService()来断开Service。当Client被摧毁时,它会和Service解绑定。但是在和服务完成交互时、或者你的activity pause时,你必须解绑定,这样Service在不被使用才能被关闭。

例子:

LocalServicemService;

privateServiceConnectionmConnection =newServiceConnection(){ // Called when the connection with the service is established

publicvoidonServiceConnected(ComponentNameclassName,IBinder service){ // Because we have bound to an explicit

// service that is running in our own process, we can

// cast its IBinder to a concrete class and directly access it. LocalBinder binder =(LocalBinder) service; mService = binder.getService(); mBound =true;

}

// Called when the connection with the service disconnects unexpectedly publicvoidonServiceDisconnected(ComponentNameclassName){ Log.e(TAG,\"onServiceDisconnected\"); mBound =false; } };

Intent intent =newIntent(this,LocalService.class);

bindService(intent, mConnection,Context.BIND_AUTO_CREATE); 复制代码

绑定一个Service时所需要注意的:

  

必须处理DeadObjectException异常。 Object是夸进程的引用计数

在Client生命周期中——启动、停止,成对的使用绑定和解绑定。

如果只是在Activity可见时才和Service交互,那么应该在onStart()时绑定,onStop()时解绑定。

 如果想要Activity即使在后台运行,stop状态,也要和Service交互,那么就应该在onCreate()时绑定,onDestroy()时解绑定。需要注意的是。这种情形,在Activity的整个生命周期中都要使用Service,此时如果Service是运行在其他进程中,那么你就加重了该进程,并且它也变得更容易被系统杀死。

 一般不要在onResume()和onPause()中进行绑定和解绑定。

Bound Service的生命周期

发送通知(Notification)给用户

Service可以通过Toast Notification或者Status Bar Notification通知用户。

 

Toast Notification:是一种现实在当前窗口,并且过一段时间后就消失的消息。 Status Bar Notification:是一种在状态栏提供icon的消息,用户可以选择它,以启动一种动作(例如:启动一个activity)。

详见《开发指南》用户接口中的通知章节。

运行一个前台Service

一个前台运行的Service,是一个用户知道的,当系统内存不足时,并不会选择杀死这样的Service来回收内存。一个前台Service必须提供一个status bar的通知,它被放在Ongoing头下——表示不能被dismissed,除非这个服务停止了或者被从前台服务移除了。

例如,一个音乐播放器,从一个Service播放音乐,需要被设置成前台运行,因为用户明显地知道它的操作。status bar中可能代表着当前的歌曲,并且允许用户启动一个activity来和播放器交互。

调用startForegound()来使你的Service运行在前台。这个方法有两个参数,一个整数代表通知的唯一的ID,一个是status bar的通知:

Notification notification =newNotification(R.drawable.icon, getText(R.string.ticker_text),

System.currentTimeMillis());

Intent notificationIntent =newIntent(this,ExampleActivity.class);

PendingIntentpendingIntent =PendingIntent.getActivity(this,0, notificationIntent,0);

notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION, notification); 复制代码

将一个Service从前台运行中移除,只需要调用stopForeground()。这个方法,有个boolean参数,表示是否也从状态栏移除通知。这个方法,并不停止service。然而,如果你停止了一个正在前台运行的service,那么它通知也将被移除。

android 2.0 之后才能使用上述两个接口,如果在更早的版本,那需要使用setFroeground()。

管理一个服务的生命周期

Service的生命周期有两种方式:

started service:当其他组件调用startService(),开始,当调用stopSelf(),或者stopService()结束,当服务停止时,系统将摧毁它。

 bound service:当其他组件调用bindService(),开始,client和service通过IBinder接口通信,当client调用unbindService()。

这两种模式,并不是完全的,因为一个已经started 的Service可以被bind。当这种情形出现时,一个stopSelf()、stopService()并不能时Service停止,只有Client也调用了unbind()之后,Service才被停止。

publicclassExampleServiceextendsService{

intmStartMode; // indicates how to behave if the service is killed IBindermBinder; // interface for clients that bind

booleanmAllowRebind;// indicates whether onRebind should be used

@Override

publicvoidonCreate(){

// The service is being created }

@Override

publicintonStartCommand(Intent intent,intflags,intstartId){ // The service is starting, due to a call to startService() returnmStartMode; }

@Override

publicIBinderonBind(Intent intent){

// A client is binding to the service with bindService() returnmBinder; }

@Override

publicbooleanonUnbind(Intent intent){

// All clients have unbound with unbindService() returnmAllowRebind; }

@Override

publicvoidonRebind(Intent intent){

// A client is binding to the service with bindService(), // after onUnbind() has already been called }

@Override

publicvoidonDestroy(){

// The service is no longer used and is being destroyed } } 复制代码

参考:

android开发指南,

http://developer.android.com/guide/topics/fundamentals/services.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务