Binder系列8—如何使用Binder(转)

一、Native层Binder

源码结构:

  • ClientDemo.cpp: 客户端程序
  • ServerDemo.cpp:服务端程序
  • IMyService.h:自定义的MyService服务的头文件
  • IMyService.cpp:自定义的MyService服务
  • Android.mk:源码build文件

1.1 服务端

#include "IMyService.h"
int main() {
    //获取service manager引用
    sp < IServiceManager > sm = defaultServiceManager();
    //注册名为"service.myservice"的服务到service manager
    sm->addService(String16("service.myservice"), new BnMyService()); ProcessState::self()->startThreadPool(); //启动线程池 IPCThreadState::self()->joinThreadPool(); //把主线程加入线程池 return 0; } 

将名为”service.myservice”的BnMyService服务添加到ServiceManager,并启动服务

1.2 客户端

#include "IMyService.h"
int main() { //获取service manager引用 sp < IServiceManager > sm = defaultServiceManager(); //获取名为"service.myservice"的binder接口 sp < IBinder > binder = sm->getService(String16("service.myservice")); //将biner对象转换为强引用类型的IMyService sp<IMyService> cs = interface_cast < IMyService > (binder); //利用binder引用调用远程sayHello()方法 cs->sayHello(); return 0; } 

获取名为”service.myservice”的服务,再进行类型,最后调用远程方法sayHello()

1.3 创建MyService

(1)IMyService.h

namespace android
{
    class IMyService : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(MyService); //使用宏,申明MyService virtual void sayHello()=0; //定义方法 }; //定义命令字段 enum { HELLO = 1, }; //申明客户端BpMyService class BpMyService: public BpInterface<IMyService> { public: BpMyService(const sp<IBinder>& impl); virtual void sayHello(); }; //申明服务端BnMyService class BnMyService: public BnInterface<IMyService> { public: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); virtual void sayHello(); }; } 

主要功能:

  • 申明IMyService
  • 申明BpMyService(Binder客户端)
  • 申明BnMyService(Binder的服务端)

(2)IMyService.cpp

#include "IMyService.h"
namespace android
{
    //使用宏,完成MyService定义 IMPLEMENT_META_INTERFACE(MyService, "android.demo.IMyService"); //客户端 BpMyService::BpMyService(const sp<IBinder>& impl) : BpInterface<IMyService>(impl) { } // 实现客户端sayHello方法 void BpMyService::sayHello() { printf("BpMyService::sayHello\n"); Parcel data, reply; data.writeInterfaceToken(IMyService::getInterfaceDescriptor()); remote()->transact(HELLO, data, &reply); printf("get num from BnMyService: %d\n", reply.readInt32()); } //服务端,接收远程消息,处理onTransact方法 status_t BnMyService::onTransact(uint_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case HELLO: { //收到HELLO命令的处理流程 printf("BnMyService:: got the client hello\n"); CHECK_INTERFACE(IMyService, data, reply); sayHello(); reply->writeInt32(2015); return NO_ERROR; } break; default: break; } return NO_ERROR; } // 实现服务端sayHello方法 void BnMyService::sayHello() { printf("BnMyService::sayHello\n"); }; } 

1.4 原理图

native_binder

1.5 运行

(1)编译生成 利用Android.mk编译上述代码,在Android的源码中,通过mm编译后,可生成两个可执行文件ServerDemo,ClientDemo。

(2)执行

首先将这两个ServerDemo,ClientDemo可执行文件push到手机

adb push ServerDemo /system/bin
adb push ClientDemo /system/bin

如果push不成功,那么先执行adb remount,再执行上面的指令;如果还不成功,可能就是权限不够。

如果上述开启成功,通过开启两个窗口运行(一个运行client端,另一个运行server端)

(3)结果

服务端:

native_server

客户端:

native_client

二、Framework层Binder

源码结构:

Server端

  1. ServerDemo.java:可执行程序
  2. IMyService.java: 定义IMyService接口
  3. MyService.java:定义MyService

Client端

  1. ClientDemo.java:可执行程序
  2. IMyService.java: 与Server端完全一致
  3. MyServiceProxy.java:定义MyServiceProxy

2.1 Server端

(1)ServerDemo.java

可执行程序

public class ServerDemo {
    public static void main(String[] args) { System.out.println("MyService Start"); //准备Looper循环执行 Looper.prepareMainLooper(); //设置为前台优先级 android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); //注册服务 ServiceManager.addService("MyService", new MyService()); Looper.loop(); } } 

(2)IMyService.java

定义sayHello()方法,DESCRIPTOR属性

public interface IMyService extends IInterface { static final java.lang.String DESCRIPTOR = "com.gityuan.frameworkBinder.MyServer"; public void sayHello(String str) throws RemoteException ; static final int TRANSACTION_say = android.os.IBinder.FIRST_CALL_TRANSACTION; } 

(3)MyService.java

public class MyService extends Binder implements IMyService{ public MyService() { this.attachInterface(this, DESCRIPTOR); } @Override public IBinder asBinder() { return this; } /** 将MyService转换为IMyService接口 **/ public static com.gityuan.frameworkBinder.IMyService asInterface( android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iInterface = obj.queryLocalInterface(DESCRIPTOR); if (((iInterface != null)&&(iInterface instanceof com.gityuan.frameworkBinder.IMyService))){ return ((com.gityuan.frameworkBinder.IMyService) iInterface); } return null; } /** 服务端,接收远程消息,处理onTransact方法 **/ @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_say: { data.enforceInterface(DESCRIPTOR); String str = data.readString(); sayHello(str); reply.writeNoException(); return true; }} return super.onTransact(code, data, reply, flags); } /** 自定义sayHello()方法 **/ @Override public void sayHello(String str) { System.out.println("MyService:: Hello, " + str); } } 

2.2 Client端

(1)ClientDemo.java

可执行程序

public class ClientDemo {

    public static void main(String[] args) throws RemoteException { System.out.println("Client start"); IBinder binder = ServiceManager.getService("MyService"); //获取名为"MyService"的服务 IMyService myService = new MyServiceProxy(binder); //创建MyServiceProxy对象 myService.sayHello("binder"); //通过MyServiceProxy对象调用接口的方法 System.out.println("Client end"); } } 

(2)IMyService.java

与Server端的IMyService是一致,基本都是拷贝一份过来。

(3)MyServiceProxy.java

public class MyServiceProxy implements IMyService { private android.os.IBinder mRemote; //代表BpBinder public MyServiceProxy(android.os.IBinder remote) { mRemote = remote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /** 自定义的sayHello()方法 **/ @Override public void sayHello(String str) throws RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(str); mRemote.transact(TRANSACTION_say, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public IBinder asBinder() { return mRemote; } } 

2.3 原理图

framework_binder

2.4 运行

首先将ServerDemo,ClientDemo可执行文件,以及ServerDemo.jar,ClientDemo.jar都push到手机

adb push ServerDemo /system/bin
adb push ClientDemo /system/bin
adb push ServerDemo.jar /system/framework adb push ClientDemo.jar /system/framework 

如果push不成功,那么先执行adb remount,再执行上面的指令;如果还不成功,可能就是权限不够。

如果上述开启成功,通过开启两个窗口运行(一个运行client端,另一个运行server端)

结果

服务端:

framework_server

客户端:

framework_client

 

转自:http://gityuan.com/2015/11/22/binder-use/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值