Android之Service

简介:

基本概念:Service是Android四大组件之一,运行在后台执行耗时操作并且不提供用户界面。其他组件(如Activity)可以通过startService启动该组件,也可以通过bindService启动并绑定该组件进行通信。


使用场景:后台下载文件,播放音乐等。


注意:Service运行在主线程中,它不会创建属于自己的线程,也不是运行在独立的线程中,所以,在使用的时候,需要自己创建线程,而不应该直接执行耗时操作,这样会引起ANR(程序未响应)错误。


Service的两种形式:

Started Service
   基本概念:其他组件(如Activity)通过调用startService()启动该Service。拥有独立的生命周期,不依赖启动它的组件。


Bound Service
    基本概念:其他组件为了与Service建立一个长时间的连接,通过调bindService启动并绑定该Service。并能与之交互(发送请求,接受响应)。生命周期依赖绑定它的组件,可以是多个组件绑定同一个Service,一旦所有绑定它的组件取消绑定,则消亡。


Service的生命周期:

Started Service,Bound Service生命周期方法流程:

技术分享


以下示例代码包含两个子Demo,所以第一个界面里面包含两个ListViewItem,分别可以进入这两个子Demo:

public class MainActivity extends Activity {

	private String[] datas = { "Started Service Demo", "Bound Service Demo" };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		setupViews();
	}

	private void setupViews() {
		//新建一个数组适配器
		ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
				MainActivity.this, android.R.layout.simple_list_item_1, datas);
		//获取到ListView控件
		ListView mListView = (ListView) findViewById(R.id.list_view_main);
		//为ListView设置适配器
		mListView.setAdapter(arrayAdapter);
		//为ListView Item设置点击监听器
		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				switch (position) {
				case 0:
					//跳转到Started Service Demo Activity
					redirectTOActivity(StartedServiceDemoActivity.class);
					break;
				case 1:
					//跳转到Bound Service Demo Activity
					redirectTOActivity(BoundServiceDemoActivity.class);
					break;

				default:
					break;
				}
			}
		});
	}
	
	//跳转到其他Activity
	private void redirectTOActivity(Class<?> destination){
		Intent intent = new Intent(MainActivity.this, destination);
		startActivity(intent);
	}
}

技术分享


以下是用StartService方法启动Service的Activity:

//操作Servie01的Activity
public class StartedServiceDemoActivity extends Activity implements OnClickListener{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_started_service_demo);
		setupViews();
	}
	
	private void setupViews()	{
		//设置两个按钮的监听器为当前Activity
		findViewById(R.id.button01).setOnClickListener(this);
		findViewById(R.id.button02).setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		
		Intent intent = new Intent(StartedServiceDemoActivity.this, Service01.class);
		
		int id = v.getId();
		switch (id) {
		case R.id.button01:
			//Start Service按钮被点击
			//启动Service01
			startService(intent);
			break;
		case R.id.button02:
			//Stop Service按钮被点击
			//停止Service01
			stopService(intent);
			break;
		default:
			break;
		}
	}
}
技术分享

以下是Service01的内容,它的onBind()和onUnBInd()不会被回调:

/**
 * 
 * Service01是以StartService方式启动,以StopService方式停止的Service
 * 如果当前无Service01实例,那么回调方法onCreate()、onStartCommand()、onStart()方法会被依次调用
 * 如果当前有Service01实例,那么回调方法onStartCommand()、onStart()方法会被依次调用
 *
 */
public class Service01 extends Service{
	
	@Override
	public IBinder onBind(Intent intent) {
		System.out.println("Service01 onBind.....");
		return null;
	}
	
	@Override
	public void unbindService(ServiceConnection conn) {
		System.out.println("Service01 onUnBind.....");
		super.unbindService(conn);
	}
	
	@Override
	public void onCreate() {
		System.out.println("Service01 onCreate.....");
		super.onCreate();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("Service01 onStartCommand.....");
		return super.onStartCommand(intent, flags, startId);
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		System.out.println("Service01 onStart.....");
	}
	
	
	@Override
	public void onDestroy() {
		System.out.println("Service01 onDestroy.....");
		super.onDestroy();
	}
	
}

以下是用BindService方式启动Service的Activity:

public class BoundServiceDemoActivity extends Activity implements OnClickListener {

	//实例化一个ServiceConnection的匿名子类对象
	private ServiceConnection serviceConnection = new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			//当解除绑定事件发生时,此方法被回调
			isBind = false;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			//当绑定事件发生时,此方法被回调
			MyBinder myBinder = (MyBinder) service; //进行一个类型转换,得到MyBinder实例
			//得到Service02实例
			mService = myBinder.getService();
			isBind = true;
			
		}
	};
	
	//定义一个Servie02类型的实例
	private  Service02 mService = null;
	//定义一个bool变量,记录当前Activity是否绑定了Servie02
	private boolean isBind = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_bound_service_demo);
		setupViews();
	}
	
	private void setupViews(){
		findViewById(R.id.button01).setOnClickListener(this);
		findViewById(R.id.button02).setOnClickListener(this);
		findViewById(R.id.button03).setOnClickListener(this);
	}
	
	@Override
	public void onClick(View v) {
		
		Intent intent = new Intent(BoundServiceDemoActivity.this, Service02.class);
		
		int id = v.getId();
		switch (id) {
		case R.id.button01:
			//开始绑定
			bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
			break;
		case R.id.button02:
			//调用Service02的业务方法
			if(mService != null){
				int x = mService.getRandomNumber();
				Toast.makeText(BoundServiceDemoActivity.this, "" + x, Toast.LENGTH_SHORT).show();
			}
			break;
		case R.id.button03:
			//解除当前Activity与Service02之间的绑定关系
			unbindService(serviceConnection);
			break;
		

		default:
			break;
		}
		
	}
}

技术分享

以下是Service02的内容,它的onStart()和onStartCommand()方法不会被回调,

这种Service它一般去编写的时候分为四个步骤,必须要有一个Binder实例来传递Service实例,具体如下:

/**
 * 
 * Service02是以BindService方式启动,以UnBindService方式解绑Service与组件之间的绑定关系,
 * 如果Service02已经绑定启动了,可以有其他的多个Activity通过BindService方式继续与其绑定,只有
 * 当所有的Activity都与Service02解除绑定关系,Service02实例才消亡
 * 
 * 如果当前无Service02实例,那么回调方法onCreate()、onBind()方法会被依次调用
 * 如果当前有Service02实例,那么回调方法onBind()方法会被依次调用
 * 如果所有绑定Service02实例的组件都调用UnBind方法,那么回调方法onUnbind()、onDestroy()方法会依次被调用
 *
 */
public class Service02 extends Service {

	// 第一步,定义一个Binder类型的子类,在子类种定义一个getService方法
	public class MyBinder extends Binder {
		public Service02 getService() {
			return Service02.this;
		}
	}
	
	//第二步,定义一个MyBinder类型的实例
	private MyBinder mBinder = new MyBinder();

	@Override
	public void onStart(Intent intent, int startId) {
		System.out.println("Service02 onStart.....");
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("Service02 onStartCommand.....");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onCreate() {
		System.out.println("Service02 onCreate.....");
		super.onCreate();
	}

	@Override
	public IBinder onBind(Intent intent) {
		System.out.println("Service02 onBind.....");
		//第三步,在onBind方法中,返回MyBinder的实例
		return mBinder;
	}

	@Override
	public boolean onUnbind(Intent intent) {
		System.out.println("Service02 onUnBind.....");
		return super.onUnbind(intent);
	}

	@Override
	public void onDestroy() {
		System.out.println("Service02 onDestroy.....");
		super.onDestroy();
	}
	
	//第四步,在Service02中定义一个业务方法,让外面与当前Service02绑定的组件能够调用此方法,来完成既定目标
	public int getRandomNumber(){
		return new Random().nextInt(100);
	}

}


最后把整个Demo的Android工程压缩文件链接如下:

Android Service Demo



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。