一、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 原理图

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)结果

服务端:

客户端:

二、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 原理图

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端)

结果

服务端:

客户端:

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


Binder系列8—如何使用Binder(转)的更多相关文章

  1. android binder机制之——(创建binder服务)

      Binder机制编程 前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解.俗话说得好"学以致用",以下我们就通过在 ...

  2. IPC 之 Binder 初识

    概述 最近在看Android 的 IPC 机制,想要系统的研究一下,然后就走到了 Binder 这里,发现这个东西真是复杂,查看了一下些文章想要记录下.想要自己写但是发现一篇文章已经写的非常好了,就转 ...

  3. 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】

    本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...

  4. Android面试官:说说你对 Binder 驱动的了解?

    面试官提了一个问题:说说你对 binder 驱动的了解.这个问题虽有些 "面试造火箭" 的无奈,可难点就是亮点.价值所在,是筛选面试者的有效手段.如果让你回答,你能说出多少呢?我们 ...

  5. 【转】Android系统开篇

    版权声明:本站所有博文内容均为原创,转载请务必注明作者与原文链接,且不得篡改原文内容.另外,未经授权文章不得用于任何商业目的. 一.引言 Android系统非常庞大.错综复杂,其底层是采用Linux作 ...

  6. SEAndroid安全机制对Binder IPC的保护分析

    在SEAndroid安全机制中,除了文件和属性,还有Binder IPC须要保护.Binder IPC是Android系统的灵魂,使用得相当广泛又频繁.比如,应用程序都是Binder IPC请求訪问系 ...

  7. Binder机制,从Java到C (6. Binder in Native : libbinder)

    1.Java和C++中的Binder 从前一篇 Binder机制,从Java到C (5. IBinder对象传递形式) 中可以看到,使用Binder的Java代码,到最后都会进入到Native环境,将 ...

  8. Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  9. Android开发之漫漫长途 IX——彻底掌握Binder

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

随机推荐

  1. zeromq编译与应用

    libzmq是c++语言开发的,正式版本在这里: https://github.com/zeromq/libzmq/releases 到这篇文件发布为止,正式稳定版是4.2.2 1,按照给出的链接下载 ...

  2. win7下自动更新svn目录

    !!注意,文件编码必须是ANSI.否则中文路径会乱码 ::这里是svn安装目录 set svnExe="C:\Program Files\TortoiseSVN\bin\TortoisePr ...

  3. 第一个WebDriver脚本

    1.cmd下安装selenium,输入pip install selenium 2.下载Firefox浏览器的驱动程序,https://github.com/mozilla/geckodriver/r ...

  4. configparser ,subprocess , xlrd ,xlwt 模块

    一,configparser模块 ''' configparser模块: 是什么: 用于解析配置文件的模块 配置文件的定义: 用于编写保存某个软件或某个系统的一系列参数的文件 设置参数 为什么需要配置 ...

  5. post processing in CFD

    post post Table of Contents 1. Post-processing 1.1. Reverse flow 1.1.1. reasons 1.1.2. solutions 1.2 ...

  6. 基本Sql语句汇总

    关于Sql语句的学习,选择的DBMS为SQL Server,Sql语句随着工作中的应用不断补充,不具备系统性,为个人笔记汇总,网上有很多优秀的资源,故不对每一处应用做过多细致的说明,后期会对部分篇幅较 ...

  7. luogu1463 [HAOI2007]反素数

    以下证明来自算法竞赛进阶指南 引理一: 答案就是 \([1,n]\) 之间约数个数最多的最小的数. 证明: 记 \(m\) 是 \([1,n]\) 之间约数个数最多的最小的数.则 \(\forall ...

  8. poj 3417 Network 题解

    题意: 先给出一棵树,然后再给出m条边,把这m条边连上,然后剪掉两条边,一条是原边,一条是新边,问有多少种方案能使图不连通. 思路: 从原边的角度看 1.树加边,一定成环,加一条(u,v)边就有u-& ...

  9. 前端学习之-- DOM

    Dom == document 1:查找 1:直接查找 document.getElementById('i1') # 根据ID获取一个标签(获取单个元素) document.getElementsB ...

  10. 【微信小程序】开发实战 之 「开发框架MINA构成」

    小程序开发框架的目标是通过尽可能简单.高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务. 微信团队为小程序提供的框架命名为MINA.MINA框架通过封装微信客户端提供的文件系统.网络通信 ...