Android中的Service:Binder,Messenger,AIDL(2)

前言

前面一篇博文介绍了关于Service的一些基本知识,包括service是什么,怎么创建一个service,创建了一个service之后如何启动它等等。在这一篇博文里有一些需要前一篇铺垫的东西,建议没有看过前一篇博文的同学先去看一下前一篇: Android中的Service:默默的奉献者 (1)

但是在前一篇博文中也有一些遗漏的东西——主要是关于bindService()这一块的具体细节。由于这一块涉及的东西还是比较多,所以在这里单独提出来了。闲话不多说,进入正文。

正文

1,bindService()

先温故一下上一篇博文的一些内容:

    这是一种比startService更复杂的启动方式,同时使用这种方式启动的service也能完成更多的事情,比如其他组件可向其发送请求,接受来自它的响应,甚至通过它来进行IPC等等。我们通常将绑定它的组件称为客户端,而称它为服务端。
    如果要创建一个支持绑定的service,我们必须要重写它的onBind()方法。这个方法会返回一个IBinder对象,它是客户端用来和服务器进行交互的接口。而要得到IBinder接口,我们通常有三种方式:继承Binder类,使用Messenger类,使用AIDL。

要完成客户端与服务端的绑定,有两件事要做。一是在客户端完成bindService的调用以及相关配置,二是在服务端里面实现onBind()方法的重写,返回一个用做信息交互的IBinder接口。接下来我们就一块一块的来看它的实现方法。

1.1,客户端的配置

客户端原则上来讲调用bindService()方法就可以了,然而事实并没有这么简单。原因就出在bindService()这个方法身上。下面我们来详细的了解一下这个方法:

public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    return mBase.bindService(service, conn, flags);
}

可以看到,bindService()方法需要三个参数,第一个是一个intent,我们都很熟悉——它和startService()里面那个intent是一样的,用来指定启动哪一个service以及传递一些数据过去。第二个参数可能就有点陌生了,这是个啥?这是实现客户端与服务端通信的一个关键类。要想实现它,就必须重写两个回调方法:onServiceConnected()以及onServiceDisconnected(),而我们可以通过这两个回调方法得到服务端里面的IBinder对象,从而达到通信的目的(下文对此会有更加详细的介绍)。下面是一个例子:

ServiceDemo mService;
//BinderDemo是在ServiceDemo里面的一个继承了Binder的内部类,这是一种得到IBinder接口的方式
//下文会有详述
ServiceDemo.BinderDemo mBinder;

private ServiceConnection mConnection = new ServiceConnection() {

    //系统会调用该方法以传递服务的 onBind() 方法返回的 IBinder。
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //当系统调用 onServiceConnected() 回调方法时,我们可以使用接口定义的方法开始调用服务。
        mBinder = (ServiceDemo.BinderDemo) service;
        //getService()是BinderDemo中的一个方法
        mService = mBinder.getService();
        //在此处可以利用得到的ServiceDemo对象调用该类中的构造方法
        Log.d(this.getClass().getSimpleName(), "onServiceConnected");
    }

    //Android系统会在与服务的连接意外中断时(例如当服务崩溃或被终止时)调用该方法。当客户端取消绑定时,系统“绝对不会”调用该方法。
    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d(this.getClass().getSimpleName(), "onServiceDisconnected");
    }
};

上面的例子实现了一个比较普通的ServiceConnection的主要功能,我们可以通过它得到目标service的对象,然后可以调用其内的共有方法,实现客户端与服务端交互的目的。

bindService()方法的第三个参数是一个int值,还叫flag(这flag立的),它是用来做什么的呢?它是一个指示绑定选项的标志,通常应该是 BIND_AUTO_CREATE,以便创建尚未激活的服务。 其他可能的值为 BIND_DEBUG_UNBIND 和 BIND_NOT_FOREGROUND,或 0(表示无)。

ok,客户端的配置到这里就差不多搞定了,接下来看看服务端需要做些什么。

1.2,服务端的配置

    如果要创建一个支持绑定的service,我们必须要重写它的onBind()方法。这个方法会返回一个IBinder对象,它是客户端用来和服务器进行交互的接口。而要得到IBinder接口,我们通常有三种方式:继承Binder类,使用Messenger类,使用AIDL。

可以看到,这里提出了一个IBinder接口的概念。那么这个IBinder接口是什么呢?它是一个在整个Android系统中都非常重要的东西,是为高性能而设计的轻量级远程调用机制的核心部分。当然,它不仅仅可以用于远程调用,也可以用于进程内调用——事实上,我们现在所说的service这里的IBinder既有可能出现远程调用的场景,比如用它来进行IPC,也有可能出现进程内调用的场景,比如用它来进行同进程内客户端与服务器的交互。IBinder的具体的工作原理在这里就不详述了,以后我应该会就这一块的内容单独写一系列的博客,在这里只需要知道它是客户端用来和服务器进行交互的接口,并且知道可以怎样通过IBinder来实现它们的交互就可以了。

一般来讲,我们有三种方式可以获得IBinder的对象:继承Binder类,使用Messenger类,使用AIDL。接下来我将就这三种方式展开来讲。

1.2.1,继承Binder类

看到这里可能有些同学会问:Binder又是什么?在这里我并不准备给出一个详尽、确切的答案——因为他太复杂了,深入的讲下去的话必将导致这篇博文失去重心。在这里我们只需要知道,它实现了IBinder接口,通过实现Binder类,

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值