「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
活动和服务进行通信
绑定本地服务调用方法的步骤:
- 在服务的内部创建一个内部binder类 并提供一个方法,可以间接调用服务的方法
- 实现服务的onbind方法,返回的就是这个内部binder类
- 在activity 绑定服务。bindService()
- 在服务成功绑定的回调方法onServiceConnected, 会传递过来一个 IBinder对象 强制类型转化为自定义的接口类型binder类,调用接口里面的方法。
下面的这段代码就实现了活动绑定并启动服务,服务通过其自建内部类MyBinder来调用服务的方法。
activity->bindService方法-》服务的onBind方法(返回自建内部类MyBinder实例)-》ServiceConnection.onServiceConnected()-》通过MyBinder实例 调用服务方法,
现在我们可以在活动中根据具体的场景来调用MyBinder中的任何 public 方法,即实现了指挥服务干什么,服务就去干什么的功能。
private void bindService(){
Intent intent = new Intent(TestActivity.this,BindService.class);
Log.i(TAG, "bindService()");
bindService(intent, conn, Context.BIND_AUTO_CREATE); //在activity 绑定服务
}
private void unBindService(){
Log.i(TAG, "unBindService() start....");
if(flag == true){
Log.i(TAG, "unBindService() flag");
unbindService(conn);
flag = false;
}
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.i(TAG, "onServiceDisconnected()");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 在服务成功绑定的回调方法onServiceConnected, 会传递过来一个 IBinder对象:service
Log.i(TAG, "onServiceConnected()");
/*通过向下转型得到了 MyBinder 的实例,有了这个实例,活动和服务之间的关系就变得非常紧密了*/
MyBinder binder = (MyBinder)service;
/*强制类型转化为自定义的接口类型MyBinder,调用接口里面的方法。*/
BindService bindService = binder.getService1();
bindService.MyMethod();
flag = true;
}
};
}
public class BindService extends Service {
private static final String TAG = "BindService";
private MyBinder myBinder = new MyBinder();
public void MyMethod(){
Log.i(TAG, "BindService-->MyMethod()");
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "BindService-->onBind()");
return myBinder;
}
//在服务的内部创建一个内部类MyBinder 提供一个方法getService1(),可以间接调用服务的方法MyMethod()
public class MyBinder extends Binder{
public BindService getService1(){
return BindService.this;
}
}
@Override
public void onCreate() {
Log.i(TAG, "BindService-->onCreate()");
super.onCreate();
}
// 只有在startService()启动Service的情况下才调用
@Override
public void onStart(Intent intent, int startId) {
Log.i(TAG, "BindService-->onStart()");
super.onStart(intent, startId);
}
//Service被启动时调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand方法被调用!");
return super.onStartCommand(intent, flags, startId);
}
//Service被关闭之前回调
@Override
public void onDestroy() {
Log.i(TAG, "BindService-->onDestroy()");
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "BindService-->onUnbind()");
return super.onUnbind(intent);
}
}
由于Service 的onStart()方法只有在startService()启动Service的情况下才调用,故使用onStart()的时候要注意这点。
与 Service 通信并且让它持续运行
如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?
可以先 startService() 然后再 bindService() 。当不需要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。
另外需要注意,任何一个服务在整个应用程序范围内都是通用的,即 Service 不仅可以和 MainActivity 绑定,还可以和任何一个其他的活动进行绑定,而且在绑定完成后它们都可以获取到相同的 Binder 实例。