Android Service详解(四)---绑定服务BoundService详解之扩展Binder类

作者: SuperBig 发布时间: 2019-09-12 浏览: 200 次 编辑

这是第四篇文章主要讲的是BoundService中使用扩展Binder类实现


一、基础知识

1.什么是绑定服务


绑定服务是客户端-服务器接口中的服务器。绑定服务可让组件(例如 Activity)绑定到服务、发送请求、接收响应,甚至执行进程间通信 (IPC)。 绑定服务通常只在为其他应用组件服务时处于活动状态,不会无限期在后台运行。


2.实现原理


应用程序组件(客户端)通过调用bindService()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,这个方法会返回一个跟服务端交互的IBinder对象。这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须穿件一个ServiceConnection类的实例,并且把这个实例传递给bindService()方法。

ServiceCOnnection对象包含了一个系统调用的传递IBinder对象的回调方法。

注意:只有Activity、Service 、和内容提供器(content provider)能够绑定服务--富裕广播接收器不能绑定服务。


3.管理绑定服务的生命周期


Bound Service的生命周期:

  • onCreate():创建服务

  • onBind():绑定服务,服务开始运行

  • onUnbind():取消绑定

  • onDestroy() :服务被停止


【详细说明:】

在程序中调用:context.bindService()会触发执行Service生命周期中的onCreate()、onBind()回调方法,此时服务开始运行;

onBind将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service运行的状态或其他操作。此后调用者(Context,例如Activity)会和Service绑定在一起;

如果调用Service的调用者Context退出了,那么会依次调用Service生命周期中的onUnbind()、onDestroy()回调方法,会让服务停止;    

所以BindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。

4.那么什么时候才算销毁呢?


如果是直接绑定的那么解绑就会销毁,如果先是StartService启动再绑定的那么需要解绑并且停止才会销毁,也就是说一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。


5.那么什么时候使用扩展的Binder类来实现BoundService呢?


如果服务是供您的自有应用专用,并且在与客户端相同的进程中运行(常见情况),则应通过扩展Binder 类并从 onBind() 返回它的一个实例来创建接口。客户端收到 Binder 后,可利用它直接访问Binder 实现中乃至 Service 中可用的公共方法。如果服务只是您的自有应用的后台工作线程,则优先采用这种方法。 不以这种方式创建接口的唯一原因是,您的服务被其他应用或不同的进程占用。

但是以上这么创建的绑定Service!!!!!!!!

如果将Service变成远程Service的话,绑定会报错:

这是由于在Bind Service按钮的点击事件里面我们会让MainActivity和MyService建立关联,但是目前MyService已经是一个远程Service了,Activity和Service运行在两个不同的进程当中,这时就不能再使用传统的建立关联的方式,程序也就崩溃了。


二、扩展Binder类实现BoundService步骤

  1. 创建一个服务重写四个方法

@Override
public void onCreate() {
    super.onCreate();
}
 
@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}
 
@Override
public boolean onUnbind(Intent intent) {
    return super.onUnbind(intent);
}
 
@Override
public void onDestroy() {
    super.onDestroy();
}


onBind()方法是绑定时调用

onUnBind()方法是解绑的时候调用


2.在Mainactivity创建一个ServiceConnection类的对象并实现。

private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
 
    }
 
    @Override
    public void onServiceDisconnected(ComponentName componentName) {
 
    }
};


onServiceConnected是绑定成功时调用的方法

onServiceDisconnected是服务异常终止时调用的方法

3.进行绑定

Intent intent = new Intent(this, MyBoundService.class);
bindService(intent, conn, BIND_AUTO_CREATE);

这个绑定是异步绑定

 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.解除绑定

unbindService(conn);

5.创建一个MyBinder类集成Binder的类

public class MyBinder extends Binder {
    public void startDownload() {
        Log.e("SuperLw", "startDownload() executed");
        // 执行具体的下载任务
    }
}

6.在MyBoundService中的onBind方法返回MyBinder对象

public class MyBoundService extends Service {
    private MyBinder mBinder = new MyBinder();
    public MyBoundService() {
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
 
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;
    }
}

7.定义一个MyBinder对象并在onServiceConnected方法中实例化

private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            myBinder = (MyBinder) iBinder;
            myBoundService = true;
 
        }
 
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            myBoundService = false;
        }
    };

8.在你想要进行通信的方法中调用方法就可以进行操作了

 public void correspondedClick(View view){
        if(myBinder!=null){
            myBinder.startDownload();
        }
 
    }


附上源码:源码


Android Service详解系列

1,Android Service详解(一)---概述4,Android Service详解(四)---绑定服务BoundService详解之扩展Binder类7,Android Service详解(七)---绑定服务BoundService详解之Messenger双向通信的实现
2,Android Service详解(二)---StartService5,Android Service详解(五)---绑定服务BoundService详解之AIDL的使用8,Android Service详解(八)---前台服务详解
3,Android Service详解(三)---IntentService6,Android Service详解(六)---绑定服务BoundService详解之AIDL的自定义属性使用



————————————————

原文链接:https://blog.csdn.net/superbiglw/article/details/53126676