Service生命周期初步了解

来源:互联网 发布:源码生成apk 编辑:程序博客网 时间:2024/06/06 03:37
 一、 Service简介
 Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider)
 它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,
 比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,
 再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。
 Service的启动有两种方式:context.startService() 和 context.bindService()

 二、 Service启动流程
 context.startService() 启动流程:
 context.startService()  -> onCreate()  -> onStart()  -> Service running  
 -> context.stopService()  -> onDestroy()  -> Service stop 

 如果Service还没有运行,则android先调用onCreate(),然后调用onStart();
 如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 
 如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,
 Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。
 所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy

 context.bindService()启动流程:
 context.bindService()  -> onCreate()  -> onBind()  -> Service running  -> onUnbind()  -> onDestroy()  -> Service stop

 onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。
 这个时候把调用者(Context,例如Activity)会和Service绑定在一起,
 Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 
 所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。
 在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),
 其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。


 三、 Service生命周期 
 Service的生命周期并不像Activity那么复杂,它只继承了onCreate()、onStart()、onDestroy()三个方法
 当我们第一次启动Service时,先后调用了onCreate()、onStart()这两个方法;当停止Service时,则执行onDestroy()方法。
 这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。

 它可以通过Service.stopSelf()方法或者Service.stopSelfResult()方法来停止自己,只要调用一次stopService()方法便可以停止服务,无论调用了多少次的启动服务方法。


四例子。创建一个MyService 的Service

package com.wyd.study.service;import com.wyd.study.DBG;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class MyService extends Service {private static final String TAG = "MyService";/** onBind里面会返回一个Binder,所以新建个实例给返回。在这个实例里面有能够 * 返回这个服务的实例。从而在ServiceConnection里面能够获取到这个Service * 能够调用这个Service相应的东西 * */private MyBinder mBinder = new MyBinder();private boolean mQuit;@Overridepublic IBinder onBind(Intent intent) {DBG.log(TAG, DBG._FUNC_());return mBinder;}@Overridepublic void onCreate() {DBG.log(TAG, DBG._FUNC_());super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {DBG.log(TAG, DBG._FUNC_());/** 这个是新的的测试线程。*/new Thread() {public void run() {mQuit = false;while (!mQuit) {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}DBG.log(TAG, DBG._FUNC_());}};}.start();// return START_NOT_STICKY;return START_STICKY;}@Overridepublic void onDestroy() {DBG.log(TAG, DBG._FUNC_());mQuit = true;super.onDestroy();}@Overridepublic boolean onUnbind(Intent intent) {DBG.log(TAG, DBG._FUNC_());return super.onUnbind(intent);}public class MyBinder extends Binder {MyService getService() {return MyService.this;}}}

操作的activity类。里面定义了四个按钮,分别是启动服务,停止服务。绑定服务,解绑服务等功能。

/** * 实验结果是 * 1、如果service没有启动过,调用bind后退出Acitivity或者调用unbind都会Destory * 2、如果service同个start启动过,只能调用stop,不然不会Destory * 3、调用bind后才能调用unbind,不然会出错. * @author WangYD * @time 2015年8月5日 *  */public class ServiceCtrlActivity extends Activity implements OnClickListener {private static final String TAG = "ServiceCtrlActivity";private TextView tv = null;private MyService mMyService = null;private static final int[] btns = new int[] { R.id.service_btn_start,R.id.service_btn_stop, R.id.service_btn_bind,R.id.service_btn_unbind, };// 这里需要用到ServiceConnection在Context.bindService和context.unBindService()里用到private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// 这里的IBinder service 是从 service.onBind 返回的,里面是通信信息的存放的地方DBG.log(TAG, DBG._FUNC_());mMyService = ((MyService.MyBinder) service).getService();tv.setText("I am from Service" + mMyService.toString());}// 类ServiceConnection中的onServiceDisconnected()方法在正常情况下是不被调用的// 它的调用时机是当Service服务被异外销毁时,例如内存的资源不足时这个方法才被自动调用。@Overridepublic void onServiceDisconnected(ComponentName name) {DBG.log(TAG, DBG._FUNC_());}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_service);tv = (TextView) findViewById(R.id.service_tv);for (int btn : btns) {findViewById(btn).setOnClickListener(this);}}@Overridepublic void onClick(View v) {Intent i = null;i = new Intent(ServiceCtrlActivity.this, MyService.class);switch (v.getId()) {case R.id.service_btn_start:startService(i);break;case R.id.service_btn_stop:stopService(i);break;case R.id.service_btn_bind:bindService(i, mServiceConnection, BIND_AUTO_CREATE);break;case R.id.service_btn_unbind:unbindService(mServiceConnection);break;default:break;}}@Overrideprotected void onDestroy() {super.onDestroy();DBG.log(TAG, DBG._FUNC_());}}

log分析1

//启动应用
08-06 09:43:33.513: I/DBG(353): MainActivity-> onCreate
//调用startService
08-06 09:43:56.262: I/DBG(353): MyService-> onCreate
08-06 09:43:56.264: I/DBG(353): MyService-> onStartCommand
//调用stopService
08-06 09:44:04.382: I/DBG(353): MyService-> onDestroy
//重新调用startService 启动service
08-06 09:44:19.658: I/DBG(353): MyService-> onCreate
08-06 09:44:19.659: I/DBG(353): MyService-> onStartCommand


//直接退出应用后再启动应用
08-06 09:44:39.105: I/DBG(353): MainActivity-> onCreate
//调用startService 启动service 并没有调用onCreate
08-06 09:44:44.187: I/DBG(353): MyService-> onStartCommand


//直接在任务管理器里面杀死应用。应用在onStartCommand 里面return START_STICKY
时,还会调用下面的两句话,说明服务还在。如果返回START_NOT_STICKY是时候。则什么也
看不到,连onDestroy都看不到。这个就很难说明服务还在不在
(实际上是不在的,可以在service增加个测试线程,不断的打印log)。区别就是START_STICKY
在被系统自己杀死进程的时候会重新启动。但是这个有个时间,所以Service会有点间隔
08-06 09:45:00.109: I/DBG(580): MyService-> onCreate
08-06 09:45:00.110: I/DBG(580): MyService-> onStartCommand

log分析2

//bindService
08-06 10:08:58.843: I/DBG(2937): MyService-> onCreate
08-06 10:08:58.851: I/DBG(2937): MyService-> onBind
08-06 10:08:58.854: I/DBG(2937): ServiceCtrlActivity-> onServiceConnected
//unbindService
08-06 10:09:07.297: I/DBG(2937): MyService-> onUnbind
08-06 10:09:07.298: I/DBG(2937): MyService-> onDestroy
//bindService
08-06 10:09:12.247: I/DBG(2937): MyService-> onCreate
08-06 10:09:12.248: I/DBG(2937): MyService-> onBind
08-06 10:09:12.259: I/DBG(2937): ServiceCtrlActivity-> onServiceConnected
//退出Activity的时候自动unbind
08-06 10:09:36.098: I/DBG(3059): MyService-> onUnbind
08-06 10:09:36.099: I/DBG(3059): MyService-> onDestroy




0 0
原创粉丝点击