Android组件——服务

服务是实现程序后台运行的解决方案,适合用于执行那些不需要和用户交互且要求长期运行的任务。

服务并不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程,当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行

  • 定义一个服务

创建一个类,并让它继承 Service,一般会重写 onBind()、onCreate()、onStartCommand()、和 onDestroy() 这几个方法

public class MyService extends Service{
	public IBinder onBind(Intent intent){
		return null;
	}
	
	public void onCreate(){
		super.onCreate();
	}
	
	public int onStartCommand(Intent intent, int flags, int startId){
		return super.onStartCommand(intent, flags, startId);
	}
	
	public void onDestroy(){
		super.onDestroy();
	}
}

然后要在 AndroidManifest.xml 文件中进行注册

<service android:name=".MyService"></service>

这样,就将一个服务完全定义好了

onCreate() 方法是在服务第一次创建的时候调用的

onStartCommand() 方法则在每次启动服务的时候都会调用

  • 启动和停止服务

在布局中添加两个按钮用来实现启动服务和停止服务的功能

public class MainActivity extends Activity implements OnClickListener{

	private Button startService;
	private Button stopService;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		
		startService = (Button)findViewById(R.id.start_service);
		stopService = (Button)findViewById(R.id.stop_service);
		startService.setOnClickListener(this);
		stopService.setOnClickListener(this);
	}
	
	public void onClick(View v){
		switch(v.getId()){
		case R.id.start_service:
			// 启动服务
			Intent startIntent = new Intent(this, MyService.class);
			startService(startIntent);
			break;
		case R.id.stop_service:
			// 停止服务
			Intent stopIntent = new Intent(this, MyService.class);
			stopService(stopIntent);
			break;
		default:
			break;
		}
	}
}



  • 活动和服务进行通信

主要要利用 Binder

实例:服务里提供一个下载功能,然后在活动中可以决定何时开始下载,以及随时查看下载进度

新建一个 DownloadBinder 类,并继承自 Binder,然后在它内部提供了开始下载和查看进度的方法,接着在 MyService 中创建 DownloadBinder 的实例,然后在 onBind() 方法里返回这个实例

public class MyService extends Service{
	
	// 创建 Binder 的实例
	private DownloadBinder mBinder = new DownloadBinder();
	
	/*
	 * 新建一个类继承 Binder
	 */
	class DownloadBinder extends Binder {
		public void startDownload() {
			Log.d("MyService", "startDownload executed");
		}
		
		public int getProgress() {
			Log.d("MyService", "getProgress executed");
			return 0;
		}
	}
	
	public IBinder onBind(Intent intent){
		// 返回 Binder 的实例
		return mBinder;
	}
	
	public void onCreate(){
		super.onCreate();
	}
	
	public int onStartCommand(Intent intent, int flags, int startId){
		return super.onStartCommand(intent, flags, startId);
	}
	
	public void onDestroy(){
		super.onDestroy();
	}
}

在布局中添加两个按钮用来实现绑定服务和取消绑定服务,修改 MainActivity 中的代码

public class MainActivity extends Activity implements OnClickListener{

	private Button startService;
	private Button stopService;
	private Button bindService;
	private Button unbindService;
	
	private MyService.DownloadBinder downloadBinder;
	
	// 创建一个 ServiceConnection 的匿名类
	private ServiceConnection connection = new ServiceConnection(){
		
		// 活动与服务解除绑定时被调用
		public void onServiceDisconnected(ComponentName name){
			
		}
		
		// 活动与服务绑定成功时被调用
		public void onServiceConnected(ComponentName name, IBinder service){
			// 向下转型,获取 DownloadBinder 的实例
			downloadBinder = (MyService.DownloadBinder)service;
			downloadBinder.startDownload();
			downloadBinder.getProgress();
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		
		startService = (Button)findViewById(R.id.start_service);
		stopService = (Button)findViewById(R.id.stop_service);
		startService.setOnClickListener(this);
		stopService.setOnClickListener(this);
		
		bindService = (Button)findViewById(R.id.bind_service);
		bindService.setOnClickListener(this);
		unbindService = (Button)findViewById(R.id.unbind_service);
		unbindService.setOnClickListener(this);
	}
	
	public void onClick(View v){
		switch(v.getId()){
		case R.id.start_service:
			// 启动服务
			Intent startIntent = new Intent(this, MyService.class);
			startService(startIntent);
			break;
		case R.id.stop_service:
			// 停止服务
			Intent stopIntent = new Intent(this, MyService.class);
			stopService(stopIntent);
			break;
		case R.id.bind_service:
			// 绑定服务
			Intent bindIntent = new Intent(this, MyService.class);
			/*
			 *  BIND_AUTO_CREATE 表示在活动和服务进行绑定后自动创建服务
			 *  这会使用服务中的 onCreate() 方法得到执行
			 *  但 onStartCommand() 方法不会执行
			 */
			bindService(bindIntent, connection, BIND_AUTO_CREATE);
			break;
		case R.id.unbind_service:
			// 解绑服务
			unbindService(connection);
			break;
		default:
			break;
		}
	}
}


首先创建了一个 ServiceConnection 的匿名类,在里面重写了 onServiceConnected() 方法和 onServiceDisconnected() 方法,这两个方法分别会在活动与服务成功以及解除绑定的时候被调用。

在 onServiceConnected() 方法中,通过向下转型得到了 DownloadBinder 的实例,可以通过这个实例根据具体的场景调用 DownloadBinder 中的任何方法。

活动和服务的绑定通过调用 bindService() 方法,BIND_AUTO_CREATE 标志表示在活动和服务进行绑定后自动创建服务,这会使得服务中的 onCreate() 方法得到执行,但 onStartCommand() 方法不会执行。


  • 服务的生命周期
  1. 调用 startService() 方法,相应的服务就会启动起来,并回调 onStartCommand() 方法。如果这个服务之前还没有创建过,onCreate() 方法会先于 onStartCommand() 方法执行。服务启动了之后会一直保持运行状态,直到 stopService() 或 stopSelf() 方法被调用。虽然每调用一次 startService() 方法,onStartCommand() 就会执行一次,但实际上每个服务都只会存在一个实例。所以不管调用了多少次 startService() 方法,只需调用一次 stopService() 或 stopSelf(),服务就会停止下来。
  2. 通过调用 bindService() 方法可以获取一个服务的持久连接,这时会回调服务中的 onBind() 方法。类似地,如果这个服务之前还没有创建过,onCreate() 方法会先于 onBind() 方法执行。之后,调用方可以获取到 onBind() 方法里返回的 IBinder 对象的实例,这样就能自由地和服务进行通信。
  3. 当调用了 startService() 方法后,又去调用 stopService() 方法,这时服务中的 onDestroy() 方法就会执行,表示服务已经销毁。类似 bindService() 方法和 unbindService() 方法组合。如果一个服务既调用了 startService() 方法,又调用了 bindService() 方法,这种情况要同时调用 stopService() 和 unbindService() 方法,onDestroy() 方法才会执行。


发布了38 篇原创文章 · 获赞 9 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章