本文章只是对Binder机制有了初步的了解。想了解更细致的话可参考http://www.cloudchou.com/page/4 Binder系列 对Binder 的详细解析。而且我这里也只不过是对这个博主文章观看后的梳理。里面的Demo都是用的这个博主的。略加了点自己的理解。
文章设计内容:
简述
IPC 与 Binder
Binder IPC 程序结构
Binder层次划分
................ 驱动层
................ 驱动适配层.
................Binder核心框架层
................Binder框架层.
................ Java 框架层与本地Binder框架层的关系
Binder C++ 框架层实现(nativeservice)
Binder Java 框架层实现(frameworkservice)
FrameWork 层 访问native Binderservice
应用层常用的Aidl 与 framework binder service 对比
简述
最近看battery(电池)底层代码的时候牵涉到binder方面的知识,对于Binder没有过过多的了解。只能学习分析了一下。不是很深入,只是明白了大概的流程。这里与大家分享一下。
IPC 与 Binder
IPC(Inter-Process Communication)进程间通信,提供了各种进程间通信的方法。
Binder是android实现的的IPC的一种机制。
例:
A进程如果要使用B进程的服务,B进程首先要注册此服务,A进程通过service mananger获取该服务的handle,通过这个handle,A进程就可以使用该服务了。A进程使用B进程的服务还意味着二者遵循相同的协议,这个协议反映在代码上就是二者要实现IBinder接口。
Binder的本质就是要把对象a从一个进程B映射到另一个进程A中,进程A中调用对象a的方法象调本地方法一样。但实际上进程B和进程A有不同的地址空间,对象a只有在进程B里有意义,但是驱动层可将进程B的对象a映射到进程A,得到对象a在进程A的表示,称之为handle,也叫句柄。这样,对象a在进程B的地址空间里有一个实际地址,在进程A里有对应的句柄,驱动会将这个句柄和对象a的实际地址映射起来。对象a对于进程B来说是本地对象,对象a对于进程A来说是远程对象,而handle对于进程A来说是对象a在进程A的引用。
Binder IPC 程序结构
Binder层次划分
驱动层
正如大家所知道的,Binder机制是需要Linux内核支持的,Android因此添加了binder驱动,binder 设备节点为/dev/binder,主设备号为10,binder驱动程序在内核中的头文件和代码路径如下:
kernel/drivers/staging/binder.h
kernel/drivers/staging/binder.c
binder驱动程序的主要作用是完成实际的binder数据传输。
驱动实现时,主要通过binder_ioctl函数与用户空间的进程交换数据(用户进程与驱动交互时使用ioctl函数,对应驱动源码的binder_ioctl函数)
驱动适配层.
主要是IPCThreadState.cpp和ProcessState.cpp,源码位于frameworks/native/libs/binder
这两个类都采用了单例模式,主要负责和驱动直接交互。
ProcessState负责打开binder设备,进行一些初始化设置并做内存映射
IPCThreadState负责直接和binder设备通信,使用ioctl读写binder驱动数据
(关于这两个类,不做过多的讲解,因为我也没细看,想了解的话可以自己查阅资料)
Binder核心框架层
Binder核心框架主要是IBinder及它的两个子类,即BBinder和BpBinder(里面的remote()返回的是一个IBinder指针),分别代表了最基本的服务端及客户端。
binder service服务端实体类会继承BnInterface,而BnInterface会继承自BBinder,利用servicemananger将BBinder对象在servicemananger注册。
客户端程序和驱动交互时只能得到远程对象的句柄handle,然后会调用ProcessState的getStrongProxyForHandle函数,利用句柄handle建立BpBinder对象,然后将它转为IBinder指针返回给调用者。这 样客户端每次调用IBinder指针的transact方法,其实是执行BpBinder的transact方法。
Binder框架层.
本地Binder框架层包含以下类(frameworks/native/libs/binder):
RefBase,IInterface,BnInterface,BpInterface,BpRefBase,Parcel 等等
Java框架层包含以下类(frameworks/base/core/java/android/os):
IBinder,Binder,IInterface,ServiceManagerNative,ServiceManager,BinderInternal,IServiceManager,ServiceManagerProxy
Java框架层的类的部分方法的实现在本地代码里(frameworks/base/core/jni)。
Java 框架层与本地Binder框架层的关系
Java层框架中的类Binder,BinderProxy,BinderInternal的native方法的实现是在源码 frameworks/base/core/jni/android_util_Binder.cpp里,Java层框架中Parcel类native方法的实现是在frameworks/base/core/jni/android_os_Parcel.cpp里。重点
在frameworks/base/core/jni/android_util_Binder.cpp 文件中,这个文件中有两个类,JavaBBinder和JavaBBinderHolder相关类。JavaBBinder继承自本地框架的BBinder,代表binder service服务端实体,而JavaBBinderHolder保存JavaBBinder指针,Java层Binder的mObject保存的是 JavaBBinderHolder指针的值,故此这里用聚合关系表示。BinderProxy的mObject保存的是BpBinder对象指针的值
图如下
然后frameworks/base/core/jni/android_util_Binder.cpp 文件中有两个重要的函数:
jobjectjavaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) :将本地IBinder对象转为Java层的IBinder对象,实际类型是BinderProxy
sp<IBinder>ibinderForJavaObject(JNIEnv* env, jobject obj) :将Java层的IBinder对象转为本地IBinder对象
注:此例子摘抄于互联网(http://www.cloudchou.com/android/post-332.html )
例子下载地址:(https://github.com/cloudchou/NativeBinderTest)
Test.h :包含需要用到的头文件,声明接口,定义操作枚举,声明binder引用类
ITestService.cpp: 接口类方法的实现
TestServer.cpp: 声明并实现binder实体类,启动binder服务,并在service manager里注册
TestClient.cpp: 声明并实现binder 引用类,测试binder服务的client
关系图:
Test.h文件 :声明接口,定义操作枚举
#ifndef TEST_H_H
#define TEST_H_H
#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
using namespace android;
namespace android
{
class ITestService : public IInterface
{
public:
DECLARE_META_INTERFACE(TestService); // declare macro
virtual void test()=0;
};
enum
{
TEST = IBinder::FIRST_CALL_TRANSACTION,
};
class BpTestService: public BpInterface<ITestService> {
public:
BpTestService(const sp<IBinder>& impl);
virtual void test();
};
}
#endif
解析:
(1)使用DECLARE_META_INTERFACE(TestService);相当于添加了下述代码:
static const android::String16 descriptor;
static android::sp<ITestService> asInterface(
const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
ITestService ();
virtual ~ITestService();
也就说添加了字段descriptor,也添加了两个成员函数asInterface,getInterfaceDescriptor, 还添加了构造器和析构器。
(2)为ITestService接口的所有方法声明枚举,一个枚举值对应ITestService接口的一个方法(Test.h)
enum{
TEST = IBinder::FIRST_CALL_TRANSACTION,
};
TEST相当于ITestService接口里的test方法,后续会为该枚举值调用test方法(Test.h)
(3)声明binder引用类BpTestService(代理类声明)
class BpTestService: public BpInterface<ITestService> {
public:
BpTestService(const sp<IBinder>& impl);
virtual void test();
};
因为实现ItestService宏定义接口DECLARE_META_INTERFACE(TestService);方法时,必须使用binder引用类,所以binder引用类需要在Test.h里声明。(注①)。
ITestService.cpp文件:实现宏定义接口DECLARE_META_INTERFACE(TestService);
#include "Test.h"
namespace android
{
IMPLEMENT_META_INTERFACE(TestService, "android.TestServer.ITestService");
}
使用IMPLEMENT_META_INTERFACE(TestService,“android.TestServer.ITestService”);相当于添加了下述代码:
/*初始化用宏DECLARE_META_INTERFACE声明的静态字段descriptor*/
const android::String16 ITestService::descriptor("android.TestServer.ITestService");
/*实现用宏DECLARE_META_INTERFACE声明的方法getInterfaceDescriptor */
const android::String16&
ITestService::getInterfaceDescriptor() const {
return ITestService::descriptor;
}
/*实现用宏DECLARE_META_INTERFACE声明的方法asInterface */
android::sp<ITestService> ITestService::asInterface(
const android::sp<android::IBinder>& obj)
{
android::sp<ITestService> intr;
if (obj != NULL) {
/*在binder实体类BnInterface里会执行queryLocalInterface*/
intr = static_cast<ITestService*>(
obj->queryLocalInterface(
ITestService::descriptor).get());
/*在binder引用类BpInterface里会创建BpInterface的子类对象*/
if (intr == NULL) {
intr = new BpTestService(obj); <strong><span style="color:red;">注①</span></strong>
}
}
return intr;
}
/*实现用宏DECLARE_META_INTERFACE声明的构造器和析构器 */
ITestService::ITestService() { }
ITestService::~ITestService() { }
TestServer.cpp 文件:声明并实现binder实体类BnInterface
#include "Test.h"
namespace android {
class BnTestService: public BnInterface<ITestService> {
public:
virtual status_t
onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
virtual void test() {
printf("Now get test\n");
}
};
status_t BnTestService::onTransact(uint_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case TEST: {
printf("got the client msg\n");
CHECK_INTERFACE(ITest, data, reply);
test();
reply->writeInt32(100);
return NO_ERROR;
}
break;
default:
break;
}
return NO_ERROR;
}
}
int main() {
sp < ProcessState > proc(ProcessState::self());
sp < IServiceManager > sm = defaultServiceManager();
sm->addService(String16("service.testservice"), new BnTestService());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
BnInterface也是binder核心库和框架中的类,表示binder实体类,在onTransact函数里,会根据客户端提交的操作代码调用不同的函数,而操作代码就是Test.h里声明的枚举值,在本实例里是TEST,我们收到test后会调用test方法。
Mian()函数里面获取servicemanager然后把本列的testservice添加进去。
TestClient.cpp文件:
#include "Test.h"
namespace android {
BpTestService::BpTestService(const sp<IBinder>& impl) :
BpInterface<ITestService>(impl) {
}
void BpTestService::test() {
printf("in the get Test\n");
Parcel data, reply;
data.writeInterfaceToken(ITestService::getInterfaceDescriptor());
remote()->transact(TEST, data, &reply);
printf("send Print %d\n", reply.readInt32());
}
}
int main() {
sp < IServiceManager > sm = defaultServiceManager();
sp < IBinder > binder = sm->getService(String16("service.testservice"));
sp<ITestService> cs = interface_cast < ITestService > (binder);
cs->test();
return 0;
}
interface_cast(binder); 实际上调用的方法是用宏DECLARE_META_INTERFACE声明的方法ITestService::asInterface,这里用了内联函数模版。
ProcessState和IPCThreadState是真正直接和binder驱动交互的类,核心库和框架层都是通过和这两个类交互才能和驱动间接交互。它们通过ioctl和binder驱动交互,ProcessState主要负责管理所有的binder引用,IPCThreadState则和 binder传输数据。(前面说过了)
测试:
流程是这样的。
TestClient.cpp -----> mian()---> getService-->interface_cast<ITestService>--> BpTestService的一个实例(BpBinder代理)---> remote发送数据给 TestServer.cpp --->
---- onTransact根据不同的方法请求,执行实际的方法,并在reply中返回值给TestClient.cpp。
注:onTransact(uint_t code, const Parcel& data, Parcel* reply,uint32_t flags)
· // code :是请求的ID号
· // data :客户端请求发送的参数
· // reply:服务器端返回的结果
· // flags:一些额外的标识,如FLAG_ONEWAY等,通常为0.
Binder Java 框架层实现(frameworkservice)
注:此例子摘抄于互联网(http://www.cloudchou.com/android/post-447.html )
例子下载地址:(https://github.com/cloudchou/FrameworkBinderTest)
ICloudManager.java:服务端和客户端共用同一个接口文件,该接口声明了binder service供外界调用的方法。
CloudManager:binder service实体类,接收客户端的调用,进行相关逻辑处理后返回结果给客户端
BServer: 创建CloudManage对象,并调用ServiceManager注册binder service
客户端:
ICloudManager.java:通过软链接实现服务端与客户端共用
CloudManagerProxy: binder service引用类,其实是binder service在客户端的代理,客户端通过该类调用服务端的操作
BClient: 测试binderservice的客户端,先通过ServiceManager获取binder对象,然后再利用它创建CloudManagerProxy对象,通过CloudManagerProxy对象调用服务端的操
Service 端:
ICloudManager.java:
package com.cloud.test;
import android.os.IInterface;
import android.os.RemoteException;
public interface ICloudManager extends IInterface {
static final java.lang.String DESCRIPTOR = "com.cloud.test.BServer";
public void print(String str) throws RemoteException ;
public int add(int a, int b) throws RemoteException ;
static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
IcloudManager 继承Iinterface接口,而这个接口类如下:
IInterface声明了asBinder方法,用于转为IBinder对象。
CloudManager:
/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package com.cloud.test;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
public class CloudManager extends Binder implements ICloudManager {
public CloudManager() {
this.attachInterface(this, DESCRIPTOR);
}
@Override
public IBinder asBinder() {
return this;
}
public static com.cloud.test.ICloudManager asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.cloud.test.ICloudManager))) {
return ((com.cloud.test.ICloudManager) iin);
}
return null;
}
@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_print: {
data.enforceInterface(DESCRIPTOR);
String str = data.readString();
print(str);
reply.writeNoException();
return true;
}
case TRANSACTION_add: {
data.enforceInterface(DESCRIPTOR);
int a = data.readInt();
int b = data.readInt();
int c = add(a, b);
reply.writeNoException();
reply.writeInt(c);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
@Override
public void print(String str) {
System.out.println(str);
}
@Override
public int add(int a, int b) {
return a + b;
}
}
注意必须从Binder继承,并实现ICloudManager接口
Bserver:
package com.cloud.test;
import android.os.Looper;
import android.os.ServiceManager;
public class BServer {
public static void main(String[] args) {
System.out.println("Cloud Manager Service Starts");
Looper.prepareMainLooper();
android.os.Process
.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
ServiceManager.addService("CloudService", new CloudManager());
Looper.loop();
}
}
实现服务端 BServer,创建CloudManager对象,并通过ServiceManager注册服务
Client端:
ICloudManager.java
客户端的ICloudManager.java里面的内容是相对地址,其实指向的服务端的ICloudManager.java。 以软连接的形式公用同一个文件。
CloudManagerProxy:
package com.cloud.test;
import android.os.IBinder;
import android.os.RemoteException;
public class CloudManagerProxy implements ICloudManager {
private android.os.IBinder mRemote;
public CloudManagerProxy(android.os.IBinder remote) {
mRemote = remote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void print(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_print, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public int add(int a, int b) throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int result=0;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
mRemote.transact(TRANSACTION_add, _data, _reply, 0);
_reply.readException();
result=_reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return result;
}
@Override
public IBinder asBinder() {
return mRemote;
}
}
代理类,在 asBinder()类里面返回IBinder. 接口方法的实现实际上是通过调用IBinder对象mRemote的transact方法将调用参数传递给服务端,然后服务端onTransact处理数据,并在 repley 参数中把参数返回。客户端再通过 repley读取服务端返回的结果,再通过返回值返回给接口方法的调用者。
Bclient:
package com.cloud.test;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
public class BClient {
/**
* Command-line entry point.
*
* @param args
* The command-line arguments
* @throws RemoteException
*/
public static void main(String[] args) throws RemoteException {
System.out.println("==========Client starts===========");
IBinder binder = ServiceManager.getService("CloudService");
ICloudManager manager = new CloudManagerProxy(binder);
manager.print("Hello world");
int result = manager.add(2, 3);
System.out.println("manager.add(2, 3)=" + result);
}
}
测试:
流程是这样的。
BClient -----> mian()---> getService--> new CloudManagerProxy(binder)-->print()与add()方法àremote发送数据给CloudManager--->
---- onTransact根据不同的方法请求,执行实际的方法,并在reply中返回值给TestClient.cpp。
注:onTransact(int code, Parcel data, Parcel reply, int flags)
· // code :是请求的ID号
· // data :客户端请求发送的参数
· // reply:服务器端返回的结果
· // flags:一些额外的标识,如FLAG_ONEWAY等,通常为0.
总结:通过这两个例子,大家可以很清晰的看到如何实现nativebinder service 与 framework binder service 。两个层“概念”上类别关系是这样的。Java 层的IBinder 接口对应C++层的 BpInterface接口(里面的remote()返回的是一个IBinder指针),Java层的Binder 对应的BnInterface 实现 onTransact方法来响应客户端的请求。
FrameWork 层 访问native Binderservice
注:此例子摘抄于互联网(http://www.cloudchou.com/android/post-468.html )
例子下载地址:(https://github.com/cloudchou/NativeBinderJavaClientDemo)
Native service文件:
ICloudManager.h , ICloudManager.cpp TestServer.cpp,TestClient.cpp(这个文件我们将忽略,这个是nativebinder 的客户端)
framework client文件:
ICloudManager.java CloudManagerProxy.java FClient.java
文件详情:
服务端
ICloudManager.h
#ifndef ICLOUDMANAGER_H_H
#define ICLOUDMANAGER_H_H
#include <stdio.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/IBinder.h>
#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
using namespace android;
namespace android
{
class ICloudManager : public IInterface
{
public:
DECLARE_META_INTERFACE(CloudManager); // declare macro
virtual void test()=0;
virtual void print(const char* str)=0;
virtual int add(int a, int b)=0;
};
enum
{
TEST = IBinder::FIRST_CALL_TRANSACTION+1,
PRINT = IBinder::FIRST_CALL_TRANSACTION+2,
ADD = IBinder::FIRST_CALL_TRANSACTION+3,
};
class BpCloudManager: public BpInterface<ICloudManager> {
public:
BpCloudManager(const sp<IBinder>& impl);
virtual void test();
virtual void print(const char* str);
virtual int add(int a, int b);
};
}
#endif
binder service接口IcloudManager ,这里请参考上面 Binder C++ 框架层实现(nativeservice)例子
ICloudManager.cpp
#include "ICloudManager.h"
namespace android
{
IMPLEMENT_META_INTERFACE(CloudManager, "com.cloud.test.ICloudManager");
}
ICloudManager接口的方法,这里请参考上面 Binder C++ 框架层实现(nativeservice)例子
TestServer.cpp
#include "ICloudManager.h"
namespace android
{
class BnCloudManager : public BnInterface<ICloudManager>
{
public:
virtual status_t
onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
virtual void test();
virtual void print(const char* str);
virtual int add(int a, int b);
};
status_t
BnCloudManager::onTransact(uint_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch (code)
{
case TEST:
{
CHECK_INTERFACE(ICloudManager, data, reply);
test();
reply->writeInt32(0);
return NO_ERROR;
}
break;
case PRINT:
{
CHECK_INTERFACE(ICloudManager, data, reply);
String16 str = data.readString16();
String8 str8 = String8(str);
print(str8.string());
reply->writeInt32(0);
return NO_ERROR;
}
break;
case ADD:
{
CHECK_INTERFACE(ITest, data, reply);
int a;
int b;
data.readInt32(&a);
data.readInt32(&b);
int c = add(a,b);
reply->writeInt32(0);
reply->writeInt32(c);
return NO_ERROR;
}
break;
default:
break;
}
return NO_ERROR;
}
void
BnCloudManager::test() {
printf("Now server receive requset from client: [call test]\n");
}
void
BnCloudManager::print(const char* str) {
printf("Now server receive requset from client: [call print %s]\n", str);
}
int
BnCloudManager::add(int a, int b) {
printf("Now server receive requset from client: [call add %d %d]\n", a, b);
return a + b;
}
}
int
main() {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
sm->addService(String16("cloudservice"), new BnCloudManager());
printf("Native binder server starts to work\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
实现服务端(TestServer.cpp) 这里请参考上面 Binder C++ 框架层实现(nativeservice)例子
框架层客户端
ICloudManager.java
package com.cloud.test;
import android.os.IInterface;
import android.os.RemoteException;
public interface ICloudManager extends IInterface {
static final java.lang.String DESCRIPTOR = "com.cloud.test.ICloudManager";
void test() throws RemoteException;
void print(String str) throws RemoteException;
int add(int a, int b) throws RemoteException;
static final int TRANSACTION_test = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}
定义接口类,这里请参考上面
Binder Java 框架层实现(framework service) 例子。 这个ICloudManager.java文件对应 ICloudManager.h 可以看到 都是定义服务方法 test(),print(),add()并且定义方法对应的常量 TEST ,PRINT,ADD. ICloudManager.java文件
对应ICloudManager.cpp 文件中的。
DESCRIPTOR :描述符号。用此描述符,标记服务。
CloudManagerProxy.java
package com.cloud.test;
import android.os.IBinder;
import android.os.RemoteException;
public class CloudManagerProxy implements ICloudManager {
private android.os.IBinder mRemote;
public CloudManagerProxy(android.os.IBinder remote) {
mRemote = remote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void print(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_print, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public int add(int a, int b) throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int result = 0;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
mRemote.transact(TRANSACTION_add, _data, _reply, 0);
_reply.readException();
result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return result;
}
@Override
public IBinder asBinder() {
return mRemote;
}
@Override
public void test() throws RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(TRANSACTION_test, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
定义接口代理类,这里通过 IBinder 的实例remote 与服务端通讯。这里请参考上面
Binder Java 框架层实现(framework service) 例子
FClient.java
package com.cloud.test;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
public class FClient {
/**
* Command-line entry point.
*
* @param args
* The command-line arguments
* @throws RemoteException
*/
public static void main(String[] args) throws RemoteException {
System.out.println("==========Client starts===========");
IBinder binder = ServiceManager.getService("cloudservice");
ICloudManager manager = new CloudManagerProxy(binder);
System.out.println("========== client call server test ===========");
manager.test();
System.out.println("========== client call server print ===========");
manager.print("Hello world");
System.out.println("========== client call server add ===========");
int result = manager.add(2, 3);
System.out.println("manager.add(2, 3)=" + result);
}
}
客户端调用:这里请参考上面 Binder Java 框架层实现(framework service) 例子
测试:
应用层常用的Aidl 与 framework binder service 对比
实现应用层的话,我们一般是写一个 aidl文件 ,比如ICloudManager.aidl ,用使用eclipse开发时,它会被自动编译成ICloudManager.java,放在gen目录下
注:此例子摘抄于互联网(http://www.cloudchou.com/android/post-458.html )
例子下载地址:(http://developer.android.com/guide/components/aidl.html )
源代码结构如下所示:
AndroidManifeset.xml:声明用到的activity,service组件
ICloudManager.aidl: binder service接口
CloudService: 创建binder service,并返回给客户端
TestAc: 测试binder service的客户端
ICloudManager.aidl 文件
package com.cloud.test;
interface ICloudManager{
void print(String str) ;
int add(int a, int b);
}
CloudService.java
package com.cloud.test;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
public class CloudService extends Service {
private final static String TAG = CloudService.class.getSimpleName();
class CloudMananger extends ICloudManager.Stub {
@Override
public void print(String str) throws RemoteException {
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid()
+ "]CloudService receive client print msg request: " + str);
}
@Override
public int add(int a, int b) throws RemoteException {
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid()
+ "[CloudService receive client add request : ");
return a + b;
}
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid() + "] onCreate");
}
private CloudMananger manager = new CloudMananger();
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid() + "] onBind");
return manager;
}
}
实现Service,覆盖onBind方法,返回binder service实体类对象
TestAc
package com.cloud.test;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
public class TestAc extends Activity {
private static final String TAG = TestAc.class.getSimpleName();
private ICloudManager manager = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid() + "] onCreate");
findViewById(R.id.btn_print).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Log.d(TAG, "=========== Client call CloudService print function");
manager.print("Hello world");
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Log.d(TAG, "======Client call CloudService add function");
int a = manager.add(3, 2);
Log.d(TAG, "======Client add function reuslt : " + a);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, CloudService.class);
bindService(intent, connection, BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(connection);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid()
+ "] onServiceDisconnected");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "[ThreadId " + Thread.currentThread().getId() + "] [ProcessId" + Process.myPid()
+ "] onServiceConnected");
manager = ICloudManager.Stub.asInterface(service);
findViewById(R.id.btn_print).setEnabled(true);
findViewById(R.id.btn_add).setEnabled(true);
}
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
对应的界面:
测试:
过程分析:Activity-->oncreate()-->onstart()-->CloudService-->onCreate()-->onBind()-->ServiceConnection-->onServiceConnected()
这样级连接到服务了。然后点击Test Print 按钮 ,再点击Test ADD 按钮。
下面附上ICloudManager.aidl自动生成的ICloudManager.java 代码:
package com.cloud.test;
public interface ICloudManager extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.cloud.test.ICloudManager {
private static final java.lang.String DESCRIPTOR = "com.cloud.test.ICloudManager";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.cloud.test.ICloudManager
* interface, generating a proxy if needed.
*/
public static com.cloud.test.ICloudManager asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.cloud.test.ICloudManager))) {
return ((com.cloud.test.ICloudManager) iin);
}
return new com.cloud.test.ICloudManager.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@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_print: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.print(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_add: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.cloud.test.ICloudManager {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void print(java.lang.String str)
throws android.os.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(Stub.TRANSACTION_print, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public int add(int a, int b) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(a);
_data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void print(java.lang.String str) throws android.os.RemoteException;
public int add(int a, int b) throws android.os.RemoteException;
}
通过此文件,可对比Binder Java 框架层实现(framework service) 例子,通过对比,可以发现跟Framework binder service 差不多,个人感觉就是把复杂模块化的部分用工具代替了
总结:android通过 Binder来实现IPC通信的。native service 与 framework service 都是相同的原理。