Service生命周期初步了解

 一、 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;

	@Override
	public IBinder onBind(Intent intent) {
		DBG.log(TAG, DBG._FUNC_());
		return mBinder;
	}

	@Override
	public void onCreate() {
		DBG.log(TAG, DBG._FUNC_());
		super.onCreate();
	}

	@Override
	public 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;
	}

	@Override
	public void onDestroy() {
		DBG.log(TAG, DBG._FUNC_());
		mQuit = true;
		super.onDestroy();
	}

	@Override
	public 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() {

		@Override
		public 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服务被异外销毁时,例如内存的资源不足时这个方法才被自动调用。
		@Override
		public void onServiceDisconnected(ComponentName name) {
			DBG.log(TAG, DBG._FUNC_());
		}

	};

	@Override
	protected 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);
		}

	}

	@Override
	public 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;

		}

	}

	@Override
	protected 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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值