目录:
一、Java程序的编译和运行
1.单步操作
PC:Hello.java 编译成 Hello.class,运行于 jvm。
javac Hello.java
java Hello
Android:Hello.java 编译成 Hello.class,通过dx指令转换成.dex格式,运行于 dalvikvm。
javac Hello.java
dx--dex --output=Hello.jar Hello.classdalvikvm-cp /mnt/android_fs/pack.jar Pack (启动方法1)
CLASSPATH=/mnt/android_fs/pack.jar app_process /mnt/android_fs Pack(启动方法2)
启动方式的差别:
dalvikvm
app_process :会创建2个binder线程: Binder_1, Binder_2 (实现读数据、解析数据、返回等操作)
2.Android编译系统(Android.mk)
把代码放到android源码中编译:
添加Androd.mk,内容类似: // 参考frameworks/base/cmds/am/Android.mk
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE :=pack
include $(BUILD_JAVA_LIBRARY)
3.使用java代码实现hello服务
(1)IHelloService.aidl
接口定义,编译生成IHelloService.java,里面有Stub : onTransact, 它会分辨收到数据然后调用sayhello, sayhello_to;
Proxy : 提供有sayhello, sayhello_to两个函数, 它们会构造数据然后发送给server。
/**{@hide} */
interfaceIHelloService
{
voidsayhello();
intsayhello_to(String name);
}
(2)IHelloService.java
/** This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/IHelloService.aidl*/
/**{@hide}*/
public interface IHelloService extendsandroid.os.IInterface
{/**Local-side IPC implementation stub class.*/
public static abstract class Stub extends android.os.Binder implementsIHelloService
{private static final java.lang.String DESCRIPTOR = "IHelloService";/**Construct the stub at attach it to the interface.*/
publicStub()
{this.attachInterface(this, DESCRIPTOR);
}/*** Cast an IBinder object into an IHelloService interface,
* generating a proxy if needed.*/
public staticIHelloService asInterface(android.os.IBinder obj)
{if ((obj==null)) {return null;
}
android.os.IInterface iin=obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceofIHelloService))) {return((IHelloService)iin);
}return newIHelloService.Stub.Proxy(obj);
}
@Overridepublicandroid.os.IBinder asBinder()
{return this;
}
@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throwsandroid.os.RemoteException
{switch(code)
{caseINTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);return true;
}caseTRANSACTION_sayhello:
{
data.enforceInterface(DESCRIPTOR);this.sayhello();
reply.writeNoException();return true;
}caseTRANSACTION_sayhello_to:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0=data.readString();int _result = this.sayhello_to(_arg0);
reply.writeNoException();
reply.writeInt(_result);return true;
}
}return super.onTransact(code, data, reply, flags);
}private static class Proxy implementsIHelloService
{privateandroid.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote=remote;
}
@Overridepublicandroid.os.IBinder asBinder()
{returnmRemote;
}publicjava.lang.String getInterfaceDescriptor()
{returnDESCRIPTOR;
}
@Overridepublic void sayhello() throwsandroid.os.RemoteException
{
android.os.Parcel _data=android.os.Parcel.obtain();
android.os.Parcel _reply=android.os.Parcel.obtain();try{
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply,0);
_reply.readException();
}finally{
_reply.recycle();
_data.recycle();
}
}
@Overridepublic int sayhello_to(java.lang.String name) throwsandroid.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.writeString(name);
mRemote.transact(Stub.TRANSACTION_sayhello_to, _data, _reply,0);
_reply.readException();
_result=_reply.readInt();
}finally{
_reply.recycle();
_data.recycle();
}return_result;
}
}static final int TRANSACTION_sayhello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_sayhello_to = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}public void sayhello() throwsandroid.os.RemoteException;public int sayhello_to(java.lang.String name) throwsandroid.os.RemoteException;
}
(3)HelloService.java
实现服务类: HelloService.java,在里面定义sayhello, sayhello_to;
importandroid.util.Slog;
/*实现Hello服务的函数 */
public class HelloService extendsIHelloService.Stub {
private static final String TAG = "HelloService";
private int cnt1 = 0;
private int cnt2 = 0;
public void sayhello() throwsandroid.os.RemoteException {
cnt1++;
Slog.i(TAG, "sayhello : cnt = "+cnt1);
}
public int sayhello_to(java.lang.String name) throwsandroid.os.RemoteException {
cnt2++;
Slog.i(TAG, "sayhello_to "+name+" : cnt = "+cnt2);
returncnt2;
}
}
(4)IGoodbyeService.aidl (同HelloService)
/**{@hide} */
interfaceIGoodbyeService
{
voidsaygoodbye();
intsaygoodbye_to(String name);
}
(5)IGoodbyeService.java
/** This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/IGoodbyeService.aidl
*/
/**{@hide} */
public interface IGoodbyeService extendsandroid.os.IInterface
{
/**Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implementsIGoodbyeService
{
private static final java.lang.String DESCRIPTOR = "IGoodbyeService";
/**Construct the stub at attach it to the interface. */
publicStub()
{
this.attachInterface(this, DESCRIPTOR);
}
/*** Cast an IBinder object into an IGoodbyeService interface,
* generating a proxy if needed.
*/
public staticIGoodbyeService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin =obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceofIGoodbyeService))) {
return((IGoodbyeService)iin);
}
return newIGoodbyeService.Stub.Proxy(obj);
}
@Override publicandroid.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throwsandroid.os.RemoteException
{
switch(code)
{
caseINTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
caseTRANSACTION_saygoodbye:
{
data.enforceInterface(DESCRIPTOR);
this.saygoodbye();
reply.writeNoException();
return true;
}
caseTRANSACTION_saygoodbye_to:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 =data.readString();
int _result = this.saygoodbye_to(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implementsIGoodbyeService
{
privateandroid.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote =remote;
}
@Override publicandroid.os.IBinder asBinder()
{
returnmRemote;
}
publicjava.lang.String getInterfaceDescriptor()
{
returnDESCRIPTOR;
}
@Override public void saygoodbye() throwsandroid.os.RemoteException
{
android.os.Parcel _data =android.os.Parcel.obtain();
android.os.Parcel _reply =android.os.Parcel.obtain();
try{
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_saygoodbye, _data, _reply, 0);
_reply.readException();
}
finally{
_reply.recycle();
_data.recycle();
}
}
@Override public int saygoodbye_to(java.lang.String name) throwsandroid.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.writeString(name);
mRemote.transact(Stub.TRANSACTION_saygoodbye_to, _data, _reply, 0);
_reply.readException();
_result =_reply.readInt();
}
finally{
_reply.recycle();
_data.recycle();
}
return_result;
}
}
static final int TRANSACTION_saygoodbye = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_saygoodbye_to = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void saygoodbye() throwsandroid.os.RemoteException;
public int saygoodbye_to(java.lang.String name) throwsandroid.os.RemoteException;
}
(6)GoodbyeService.java
importandroid.util.Slog;/*实现Goodbye服务的函数*/
public class GoodbyeService extendsIGoodbyeService.Stub {private static final String TAG = "GoodbyeService";private int cnt1 = 0;private int cnt2 = 0;public void saygoodbye() throwsandroid.os.RemoteException {
cnt1++;
Slog.i(TAG,"saygoodbye : cnt = "+cnt1);
}public int saygoodbye_to(java.lang.String name) throwsandroid.os.RemoteException {
cnt2++;
Slog.i(TAG,"saygoodbye_to "+name+" : cnt = "+cnt2);returncnt2;
}
}
(7)TestServer.java (addService, 循环)
importandroid.util.Slog;
importandroid.os.ServiceManager;
/*1. addService
* 2. while(true) { read data, parse data, call function, reply }
*/
public classTestServer {
private static final String TAG = "TestServer";
public static voidmain(String args[])
{
/*add Service */Slog.i(TAG, "add hello service");
ServiceManager.addService("hello", newHelloService());
Slog.i(TAG, "add goodbye service");
ServiceManager.addService("goodbye", newGoodbyeService());
while (true)
{
try{
Thread.sleep(100);
} catch(Exception e){}
}
}
}
(8)TestClient.java (getService, 调用sayhello,sayhello_to(来自Proxy))
importandroid.util.Slog;importandroid.os.ServiceManager;importandroid.os.IBinder;/*1. getService
* 2. 调用服务的sayhello,sayhello_to
**/
/*test_client [name]*/
public classTestClient {private static final String TAG = "TestClient";public static voidmain(String args[])
{if (args.length == 0)
{
System.out.println("Usage: need parameter: [name]");return;
}if (args[0].equals("hello"))
{/*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);
}
}
}else if (args[0].equals("goodbye"))
{/*1. getService*/IBinder binder= ServiceManager.getService("goodbye");if (binder == null)
{
System.out.println("can not get goodbye service");
Slog.i(TAG,"can not get goodbye service");return;
}
IGoodbyeService svr=IGoodbyeService.Stub.asInterface(binder);if (args.length == 1)
{try{
svr.saygoodbye();
System.out.println("call saygoodbye");
Slog.i(TAG,"call saygoodbye");
}catch(Exception e) {}
}else{try{int cnt = svr.saygoodbye_to(args[1]);
System.out.println("call saygoodbye_to "+args[1]+" : cnt = "+cnt);
Slog.i(TAG,"call saygoodbye_to "+args[1]+" : cnt = "+cnt);
}catch(Exception e) {}
}
}
}
}
(9)Android.mk
# Copyright 2008The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES :=HelloService.java IHelloService.java GoodbyeService.java IGoodbyeService.java TestServer.java
LOCAL_MODULE :=TestServer
include $(BUILD_JAVA_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES :=HelloService.java IHelloService.java GoodbyeService.java IGoodbyeService.java TestClient.java
LOCAL_MODULE :=TestClient
include $(BUILD_JAVA_LIBRARY)
编译&测试说明:
(1) AIDL
1. 把 IHelloService.aidl, IGoodbyeService.aidl 放入 frameworks/base/core/java/android/os
2. 修改 frameworks/base/Android.mk 添加一行
core/java/android/os/IVibratorService.aidl \
+ core/java/android/os/IHelloService.aidl \
+ core/java/android/os/IGoodbyeService.aidl \
3. mmm frameworks/base
4. 它会生成:
./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IHelloService.java
./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IGoodbyeService.java
(2) 编译:
把程序放到 /work/android-5.0.2/frameworks/testing/APP_0005_Binder_JAVA_App
执行:
cd /work/android-5.0.2
. setenv
lunch // 选择单板
mmm frameworks/testing/APP_0005_Binder_JAVA_App
它会生成 TestServer.jar, TestClient.jar
复制文件到NFS目录
cp /work/android-5.0.2/out/target/product/tiny4412/system/framework/Test*.jar /work/nfs_root/android_fs/
(3) 测试:
logcat TestServer:* TestClient:* HelloService:* *:S &
CLASSPATH=/mnt/android_fs/TestServer.jar app_process / TestServer &
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient hello
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient hello 100ask.taobao.com
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient goodbye
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient goodbye weidongshan
二、内部机制
1.Client端1.1 ServiceManagerProxy中mRemote的构造 (用于addService/getService)
使用0直接构造出一个java BinderProxy对象
getIServiceManager().addService / getIServiceManager().getService
getIServiceManager()
return ServiceManagerNative.asInterface(BinderInternal.getContextObject())
a. BinderInternal.getContextObject() // 得到了一个Java BinderProxy对象, 其中mObject指向new BpBinder(0);
它是一个JNI调用,对应 android_os_BinderInternal_getContextObject // android_util_Binder.cpp
android_os_BinderInternal_getContextObject
sp b = ProcessState::self()->getContextObject(NULL);
getStrongProxyForHandle(0);
b = new BpBinder(handle); // mHandle = 0
return javaObjectForIBinder(env, b); // b = new BpBinder(0), mHandle = 0
// 使用c代码调用NewObject来创建JAVA BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
// 设置该对象的mObject = val.get = b = new BpBinder(0)
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
return object;
b. ServiceManagerNative.asInterface
new ServiceManagerProxy(obj); // obj = BinderProxy对象
mRemote = obj = BinderProxy对象, 其中mObject指向new BpBinder(0);
1.2 hello服务里的mRemote如何构造
a. IBinder binder = ServiceManager.getService("hello");
它的返回值就是一个java BinderProxy对象, 其中的mObject=new BpBinder(handle)
new ServiceManagerProxy().getService("hello")
....
IBinder binder = reply.readStrongBinder();
nativeReadStrongBinder // Parcel.java
nativeReadStrongBinder是一个JNI调用, 对应的代码是 android_os_Parcel_readStrongBinder
android_os_Parcel_readStrongBinder
// 把java Parce对象转换为c++ Parcel对象
// client程序向sevice_manager发出getService请求,
// 得到一个回复reply, 它里面含有flat_binder_object
// 它被封装成一个c++ Parcel对象
Parcel* parcel = reinterpret_cast(nativePtr);
/* parcel->readStrongBinder()应该是一个 new BpBinder(handle)
* unflatten_binder(ProcessState::self(), *this, &val);
* *out = proc->getStrongProxyForHandle(flat->handle);
* b = new BpBinder(handle);
*/
// 它会创建一个java BinderProxy对象, 其中的mObject=new BpBinder(handle)对象
return javaObjectForIBinder(env, parcel->readStrongBinder());
b. IHelloService svr = IHelloService.Stub.asInterface(binder);
new IHelloService.Stub.Proxy(obj); // obj = 步骤a得到的binder
mRemote = remote;
1.3 现在知道了:mRemote就是一个java BinderProxy 对象
看一下mRemote.transact()
transactNative(code, data, reply, flags);
它是一个JNI调用,对应android_os_BinderProxy_transact
android_os_BinderProxy_transact
// 从java BinderProxy对象中把mObject取出, 它就是一个BpBinder对象
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
// 然后调用BpBinder的transact
status_t err = target->transact(code, *data, reply, flags);
2.Server端
2.1 server如何读取数据
使用app_process来启动server进程,
/*测试指令*/
logcat TestServer:* TestClient:* HelloService:* *:S &CLASSPATH=/mnt/android_fs/TestServer.jar app_process / TestServer &CLASSPATH=/mnt/android_fs/TestClient.jar app_process /TestClient hello
CLASSPATH=/mnt/android_fs/TestClient.jar app_process /TestClient hello sheldon/*参考源码*/
//app_process: frameworks\base\cmds\app_process\app_main.cpp
它会先创建子线程(前面示例提到的两个binder线程:Binder_1, Binder_2):
AppRuntime::onStarted()
proc->startThreadPool();
spawnPooledThread(true);
sp t = new PoolThread(isMain);
t->run(name.string());
// 它会创建子线程, 并执行threadLoop
IPCThreadState::self()->joinThreadPool(mIsMain);
{
do {
result = getAndExecuteCommand();
result = talkWithDriver();
result = executeCommand(cmd);
对于BR_TRANSACTION数据,
sp b((BBinder*)tr.cookie); //将.cookie转换成BBinder对象
error = b->transact(tr.code, buffer, &reply, tr.flags); //并调用其transact方法
} while(...)
}
2.2 server读到数据后怎么调用服务PRC层的onTransact函数
在addService时设置.ptr/.cookie
ServiceManager.addService("hello", new HelloService());
结论:
① addService会通过JNI调用c++函数:
创建一个BBinder派生类JavaBBinder对象,
它的.mObject指向JAVA对象: new HelloService()
它含有onTransact函数
把这个对象存入.cookie(最终存入binder驱动中该服务对应的binder_node.cookie)
② server进程从驱动中读到数据,里面含有.cookie
把它转换为BBinder对象,
调用它的transact函数
最终调用到派生类JavaBBinder中定义的onTransact函数
③ JavaBBinder中定义的onTransact函数(c++)
它通过JNI调用java Binder的execTransact方法,
然后调用Binder派生类IHelloService.Stub中定义的onTransact函数(JAVA)
④ IHelloService.Stub中定义的onTransact函数(JAVA):
分析数据
调用sayhello/sayhello_to
源码阅读:
(1) ServiceManager.addService("hello", new HelloService());
ServiceManagerProxy.addService:
// Parcel.java
data.writeStrongBinder(service);
nativeWriteStrongBinder(mNativePtr, val); // val = service = new HelloService()
它是一个JNI调用,对应android_os_Parcel_writeStrongBinder(c++)
(2) android_os_Parcel_writeStrongBinder(c++)
它会构造一个JavaBBinder对象(c++),.mObject=new HelloService() JAVA对象
然后让.cookie=JavaBBinder对象(c++)
// 把Java Parcel转换为c++ Parcel
Parcel* parcel = reinterpret_cast(nativePtr);
// .cookie = ibinderForJavaObject(env, object)得到一个JavaBBinder对象
parcel->writeStrongBinder(ibinderForJavaObject(env, object))
(3) ibinderForJavaObject(env, object) //object = new HelloService()
把一个Java对象(new HelloService())转换为c++ IBinder对象
JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
b = new JavaBBinder(env, obj); // obj = new HelloService()
mObject = new HelloService()
(4) 从驱动中得过了.cookie, 它是一个JavaBBinder对象
调用它的transact函数,导致JavaBBinder对象的onTransact被调用
JavaBBinder::onTransact (调用java里的某个函数)
// mObject指向 HelloService对象
// gBinderOffsets.mExecTransact指向: java Binder类中的execTransact方法
// 调用HelloService(派生自Binder)对象中的execTransact方法
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast(&data), reinterpret_cast(reply), flags);
(5) java Binder execTransact:
res = onTransact(code, data, reply, flags);
调用HelloService中的onTransact方法(来自IHelloService.Stube)
分辨数据
调用sayhello/sayhello_to
-end-