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

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

这是第四篇文章主要讲的是BoundService中使用扩展Binder类实现
回顾
Android Service详解(一)---概述和StartService
Android Service详解(二)---StartService
Android Service详解(三)---IntentService
一、基础知识
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关联又处理停止状态的时候才会被销毁。

4.那么什么时候使用扩展的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)