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
- Android Binder通信学习
- Android Binder通信机制学习
- Android Binder通信机制学习
- Android Binder通信机制学习
- Android Binder通信机制学习(一)
- Android Binder通信机制学习(二)
- Android Binder 通信机制学习(三)
- Android Binder 通信机制学习(四)
- Binder通信学习总结
- Android Binder通信机制
- android 使用Binder通信
- android之binder通信
- Android Binder通信机制
- android binder 通信
- Android Binder通信
- Android进程间通信机制——Binder学习
- Android学习笔记1-2--通信2--Binder
- Android Java Binder 通信机制
- WebView
- C#语言之“string格式的日期时间字符串转为DateTime类型”的方法
- 什么是Maven
- 《UIScrollView滚动视图》
- C# 爬虫,抓取网页数据
- Android Binder通信学习
- Linux命令---用户设置
- Android数据查询query函数参数解析
- 数字三角形问题
- Android中多次弹出相同Toast提示框长时间不消失
- Java线程池
- clipChildren和android:clipToPadding属性的使用
- Android 插件化开发(一)
- Redis代码阅读3--Redis网络监听(2)