Android Binder通信学习

来源:互联网 发布:网络大电影的宣传 编辑:程序博客网 时间:2024/06/10 10:08

Android Binder通信学习。

以Hello为例说明设计的几个概念关系:

IhelloService.h : 提供给应用程序使用的类接口,注意是说明服务能够提供的哪些操作接口。

【注意】实际不只是定义一个接口类,还继承该接口并添加虚接口onTransact后定义了一个抽象类BnHelloService

class IHelloService: public IInterface        {        public:            DECLARE_META_INTERFACE(HelloService);   /* 此宏声明了接口IHelloService::getInterfaceDescriptor 和 IHelloService::asInterface(这个接口可以生成一个Bp实例) */            virtual void sayhello(void) = 0;            virtual int sayhello_to(const char *name) = 0;        };        class BnHelloService: public BnInterface<IHelloService>        {        public:            virtual status_t    onTransact( uint32_t code,                                            const Parcel& data,                                            Parcel* reply,                                            uint32_t flags = 0);            virtual void sayhello(void);            virtual int sayhello_to(const char *name);        };

BnHelloService.cpp : 为了之后可以用BnHelloService实例化对象,需要对BnHelloService完成接口中定义的虚函数.【这个是实际去干活的服务,’别人‘只是给他发需求】

        status_t BnHelloService::onTransact( uint32_t code,                                    const Parcel& data,                                    Parcel* reply,                                    uint32_t flags)        {            switch (code) {                case HELLO_SVR_CMD_SAYHELLO:                     sayhello();                    break;                case HELLO_SVR_CMD_SAYHELLO_TO:                     sayhello_to(name8.string());                     break;            }            return NO_ERROR;        }        void BnHelloService::sayhello(void)        {            static int cnt = 0;            ALOGI("say hello : %d\n", ++cnt);        }        int BnHelloService::sayhello_to(const char *name)        {            static int cnt = 0;            ALOGI("say hello to %s : %d\n", name, ++cnt);            return cnt;        }

BpHelloService.cpp : 继承抽象的接口类,并去实现虚函数,这样才能实例化对象,成为给服务发需求的‘别人’。【BpXXService负责给服务发需求,这么说服务并不是谁叫我干活就干,我只听Bp的】

        class BpHelloService: public BpInterface<IHelloService>        {        public:            BpHelloService(const sp<IBinder>& impl)                : BpInterface<IHelloService>(impl)            {            }            void sayhello(void)            {                Parcel data, reply;                data.writeInt32(0);                data.writeString16(String16("IHelloService"));                remote()->transact(HELLO_SVR_CMD_SAYHELLO, data, &reply);            }            int sayhello_to(const char *name)            {                Parcel data, reply;                int exception;                data.writeInt32(0);                data.writeString16(String16("IHelloService"));                data.writeString16(String16(name));                remote()->transact(HELLO_SVR_CMD_SAYHELLO_TO, data, &reply);                exception = reply.readInt32();                if (exception)                    return -1;                else                    return reply.readInt32();                }        };        IMPLEMENT_META_INTERFACE(HelloService, "android.media.IHelloService");/* 此宏具体实现了接口IHelloService::getInterfaceDescriptor 和 IHelloService::asInterface */

HelloServer.c : 实现的最底层接收请求的服务器,提供怎样的服务呢?只提供这个里面提供的服务BnHelloService!

        int main(void)        {            /* 打开biner并mmap进内存 */            sp<ProcessState> proc(ProcessState::self());            /* 获得 BnServiceManager */            sp<IServiceManager> sm = defaultServiceManager();            /* 添加服务 */            sm->addService(String16("hello"), new BnHelloService());            /* 循环体,不断获取服务并处理 */            ProcessState::self()->startThreadPool();            IPCThreadState::self()->joinThreadPool();            return 0;        }

HelloClient.c : 最底层发请求的客户端,这才是满肚子需求的底层人民啊。

        int main(int argc, char **argv)        {            int cnt;            /* 打开biner并mmap进内存 */            sp<ProcessState> proc(ProcessState::self());            /* 获得 BpServiceManager */            sp<IServiceManager> sm = defaultServiceManager();            /* 获得 根据hello名字 获取服务  */            sp<IBinder> binder =                sm->getService(String16("hello"));            if (binder == 0)            {                ALOGI("can't get hello service\n");                return -1;            }        /* Service肯定是 BpHelloService 指针??        * interface_cast<IHelloService>(binder)  ->            IHelloService::asInterface(binder);(IMPLEMENT_META_INTERFACE宏中定义)            *【结果:在下面代码中分配一个BpHelloService实例指针】             */            sp<IHelloService> service =                interface_cast<IHelloService>(binder);            /* 调用 BpHelloService提供的函数  */            service->sayhello();            ALOGI("client call sayhello");            return 0;        }

好了,下面来总结下:背景是世界的阶级斗争依然是如此的激烈,因此不管干啥我们都分等级,Binder服务也是如此,有需求只向上级反映,由上级出处理:

                BpServiceManager <- HelloClient                     |                    \ /                BnServiceManager -> HelloServer


Binder的java实现。

IHelloService.aidl : Android接口描述文件,只要用户定义自己需要提供的接口,然后放到frameworks/base/core/java/android/os下,并修改

                        frameworks/base/Android.mk  添加一行                        core/java/android/os/IHelloService.aidl\代码:
/** {@hide} */interface IHelloService{    void sayhello();    int sayhello_to(String name);}

IHelloService.java : 由aidl文件编译出来的接口类,里面除了用户自定义的接口外还包含一个 stub 的内部类。

【stub】:为屏蔽客户调用远程主机上的对象,必须提供某种方式来模拟本地对象,这种本地对象称为存根(stub),根负责接收本地方法调用,并将它们委派给各自的具体实现对象代码只保留框架:
public interface IHelloService extends android.os.IInterface{    /** Local-side IPC implementation stub class. */    public static abstract class Stub extends android.os.Binder implements IHelloService    {        private static final java.lang.String DESCRIPTOR = "IHelloService";        /** Construct the stub at attach it to the interface. */        public Stub()        {            this.attachInterface(this, DESCRIPTOR);        }        /**         * Cast an IBinder object into an IHelloService interface,         * generating a proxy if needed.         */        public static IHelloService asInterface(android.os.IBinder obj)        {            return new IGoodbyeService.Stub.Proxy(obj);  /* 客户端获取服务后,需要转化为proxy才能进行最终的接口调用  */        }        @Override public android.os.IBinder asBinder()        {            return this;        }        /* 实际处理需求的服务端,类似于C++ binder中的BnXxService功能,用于接收需求并实际出执行需求任务 */        @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException        {           switch (code)            {                case INTERFACE_TRANSACTION:                {                    reply.writeString(DESCRIPTOR);                    return true;                }                case TRANSACTION_saygoodbye:                {                    data.enforceInterface(DESCRIPTOR);                    this.saygoodbye();                      /* 调用本stub中定义的接口函数 */                    reply.writeNoException();                    return true;                }                case TRANSACTION_saygoodbye_to:                {                    data.enforceInterface(DESCRIPTOR);                    java.lang.String _arg0;                    _arg0 = data.readString();                    int _result = this.saygoodbye_to(_arg0);  /* 调用本stub中定义的接口函数 */                    reply.writeNoException();                    reply.writeInt(_result);                    return true;                }            }        }        private static class Proxy implements IGoodbyeService  /* 代理类,类似于C++ binder中的BpXxService,用于接收需求并封装数据发生需求给服务端 */        {          mRemote.transact(Stub.TRANSACTION_saygoodbye_to, _data, _reply, 0);        }    }    public void sayhello() throws android.os.RemoteException;    public int sayhello_to(java.lang.String name) throws android.os.RemoteException;}

Helloservice.java : 服务器代码,非常简单,继承IHelloService.Stub的接口,并实现最终干活的代码。

public class HelloService extends IHelloService.Stub {    private static final String TAG = "HelloService";    private int cnt1 = 0;    private int cnt2 = 0;    public void sayhello() throws android.os.RemoteException {        cnt1++;        Slog.i(TAG, "sayhello : cnt = "+cnt1);    }    public int sayhello_to(java.lang.String name) throws android.os.RemoteException {        cnt2++;        Slog.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);        return cnt2;    }}

TestServer.java : 用户这边提供服务的代码,目的就是注册一个服务

public class TestServer {    private static final String TAG = "TestServer";    public static void main(String args[])    {        /* add Service */        Slog.i(TAG, "add hello service");        ServiceManager.addService("hello", new HelloService()); /* 此处添加负责服务器任务的类 */        while (true)        {            try {                Thread.sleep(100);            } catch (Exception e){}        }    }}

TestClient.java : 最底层发需求的用户代码。

public class TestClient {    private static final String TAG = "TestClient";    public static void main(String args[])    {        /* 1. getService */        IBinder binder = ServiceManager.getService("hello");        if (binder == null)        {            System.out.println("can not get hello service");            Slog.i(TAG, "can not get hello service");            return;        }        IHelloService svr = IHelloService.Stub.asInterface(binder); /* 得到接口的代理 */        if (args.length == 1)        {                try {                svr.sayhello();                System.out.println("call sayhello");                Slog.i(TAG, "call sayhello");            } catch (Exception e) {}        }        else        {                try {                int cnt = svr.sayhello_to(args[1]);                System.out.println("call sayhello_to "+args[1]+" : cnt = "+cnt);                Slog.i(TAG, "call sayhello_to "+args[1]+" : cnt = "+cnt);            } catch (Exception e) {                    System.out.println("call sayhello_to , err :"+e);                    Slog.i(TAG, "call sayhello_to , err : "+e);            }        }    }}

0 0
原创粉丝点击