Binder机制初解

      本文章只是对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 layer



驱动层

正如大家所知道的,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对象


Binder C++ 框架层实现(nativeservice)

注:此例子摘抄于互联网(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.cppTestClient.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 都是相同的原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值