Android Service(二)活动和服务进行通信

1,543 阅读3分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

活动和服务进行通信

绑定本地服务调用方法的步骤:

  1. 在服务的内部创建一个内部binder类 并提供一个方法,可以间接调用服务的方法
  2. 实现服务的onbind方法,返回的就是这个内部binder类
  3. 在activity 绑定服务。bindService()
  4. 在服务成功绑定的回调方法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 实例。