绑定服务BindService详解
[TOC]
文章参考:https://blog.csdn.net/SuperBigLw/article/details/53126676
文章参考:https://www.heqiangfly.com/2015/12/20/android-knowledge-about-service/
一、概述
绑定服务是客户端-服务器接口中的服务器。绑定服务可让组件(例如 Activity)绑定到服务、发送请求、接收响应,甚至执行进程间通信 (IPC)。 绑定服务通常只在为其他应用组件服务时处于活动状态,不会无限期在后台运行。
二、实现原理
应用程序组件(客户端)通过调用bindService()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,这个方法会返回一个跟服务端交互的IBinder对象。这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须穿件一个ServiceConnection类的实例,并且把这个实例传递给bindService()方法。
ServiceCOnnection对象包含了一个系统调用的传递IBinder对象的回调方法。
注意:只有Activity、Service 、和内容提供器(content provider)能够绑定服务。
广播接收器不能绑定服务。
三、生命周期
Bind Service的生命周期:
- onCreate(): 创建服务
- onBind(): 绑定服务,服务开始运行
- onUnbind(): 取消绑定
- onRebind(): 重新绑定服务的前提条件:服务处于启动状态,且onUnbind方法返回true。
- onDestroy(): 服务被停止
在程序中调用:context.bindService()会触发执行Service生命周期中的onCreate()、onBind()回调方法,此时服务开始运行;
onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。此后调用者(Context,例如Activity)会和Service绑定在一起;
如果调用Service的调用者Context退出了,那么会依次调用Service生命周期中的onUnbind()、onDestroy()回调方法,会让服务停止;
所以BindService的生命周期为:onCreate –> onBind(只一次,不可多次绑定) –> onUnbind –> onDestory。
四、Service的销毁
如果是直接绑定的那么解绑就会销毁,如果先是StartService启动再绑定的那么需要解绑并且停止才会销毁,也就是说一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。
五、如何使用Binder类来BindService
如果服务是供您的自有应用专用,并且在与客户端相同的进程中运行(常见情况),则应通过扩展Binder 类并从 onBind() 返回它的一个实例来创建接口。客户端收到 Binder 后,可利用它直接访问Binder 实现中乃至 Service 中可用的公共方法。如果服务只是您的自有应用的后台工作线程,则优先采用这种方法。
不以这种方式创建接口的唯一原因是,您的服务不能被其他应用或不同的进程占用。
但是以上这么创建的绑定Service!!!!!!!!
如果将Service变成远程Service的话,绑定会报错:
这是由于在Bind Service按钮的点击事件里面我们会让MainActivity和MyService建立关联,但是目前MyService已经是一个远程Service了,Activity和Service运行在两个不同的进程当中,这时就不能再使用传统的建立关联的方式,程序也就崩溃了。
六、使用方法
1.创建一个服务重写四个方法
1 | @Override |
onBind()方法是绑定时调用
onUnBind()方法是解绑的时候调用
2.在Mainactivity创建一个ServiceConnection类的对象并实现。
1 | private ServiceConnection conn = new ServiceConnection() { |
onServiceConnected是绑定成功时调用的方法
onServiceDisconnected是服务异常终止时调用的方法
3.进行绑定
1 | Intent intent = new Intent(this, MyBoundService.class); |
这个绑定是异步绑定
bindService(Intent,ServiceConnection对象,常量)的参数说明
第一个参数:Intent指示对应的Service对象
第二个参数:实现了 ServiceConnection接口的对象
第三个参数:Flags
在进行服务绑定时,其标志位可以为:
- BIND_AUTO_CREATE
- BIND_DEBUG_UNBIND
- BIND_NOT_FOREGROUND
BIND_AUTO_CREATE表示当收到绑定请求时,如果服务尚未创建,则即刻创建,在系统内存不足,需要先销毁优先级组件来释放内存,且只有驻留该服务的进程成为被销毁对象时,服务才可被销毁;
BIND_DEBUG_UNBIND通常用于调试场景中判断绑定的服务是否正确,但其会引起内存泄漏,因此非调试目的不建议使用;
BIND_NOT_FOREGROUND表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行,该标志位在Froyo中引入。
4.解除绑定
1 | unbindService(conn); |
5.创建一个MyBinder类集成Binder的类
1 | public class MyBinder extends Binder { |
6.在MyBoundService中的onBind方法返回MyBinder对象
1 | public class MyBoundService extends Service { |
7.定义一个MyBinder对象并在onServiceConnected方法中实例化
1 | private ServiceConnection conn = new ServiceConnection() { |
8.在你想要进行通信的方法中调用方法就可以进行操作了
1 | public void correspondedClick(View view){ |