比如现在想在MyService里提供一个下载功能,然后在活动中可以决定何时开始下载,以及随时查看下载进度。实现这个功能的思路是创建一个专门的Binder对象来对下载功能进行管理。代码如下所示:
public class MyService extends Service{
private DownloadBinder mBinder = new DownloadBinder();
class DownloadBinder extend Binder{
public void startDownload(){
Log.d("MyService", "startDownload executed");
}
public int getProgress(){
Log.d("MyService", "getProgress executed");
return 0;
}
}
@Override
public IBinder onBind(Intent intent){
return mBinder;
}
...
}
当一个活动和服务绑定了之后,就可以调用该服务里的Binder提供的方法了。下面来看一下在活动中如何去调用服务里的这些方法:
public class BindServiceActivity extends AppCompatActivity implements View.OnClickListener{
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
downloadBinder = (MyService.DownloadBinder)service;
downloadBinder.startDownload();
downloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bind_service);
...
Button bindService = (Button)findViewById(R.id.bind_service);
Button unbindService = (Button)findViewById(R.id.unbind_service);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
...
case R.id.bind_service:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE); //绑定服务
break;
case R.id.unbind_service:
unbindService(connection); //解绑服务
break;
default:
break;
}
}
}
现在我们就可以在活动中根据具体的场景来调用DownloadBinder中的任何public方法了。
说明:bindService中的第三个参数BIND_AUTO_CREATE是一个标志位,表示在活动和服务进行绑定后自动创建服务。
销毁服务的特殊情况
我们对一个服务既调用了startService()方法,又调用了bindService()方法,这种情况下该如何让服务销毁呢?根据Android系统的机制,一个服务只要被启动或者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被销毁。所以,这种情况下要同时调用stopService()和unbindService()方法,onDestroy()方法才会执行。