AIDL:Android InterfaceDefinition Language,即Android接口定义语言。其实就是用来生成java层对应的binder 接口,还是以之前的ItestService为例,在android studio中我们创建如下一个aidl文件。
ITestService.aidl
// ITestService.aidl
package com.hxiong;
// Declare any non-default types here with import statements
interface ITestService {
//
int test(int api);
}
点击构建构成后,会在app\build\generated\source\aidl\debug\com\hxiong 目录下生成一个ITestService.java的文件
文件里面的内容如下
package com.hxiong;
// Declare any non-default types here with import statements
public interface ITestService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.hxiong.ITestService
{
private static final java.lang.String DESCRIPTOR = "com.hxiong.ITestService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.hxiong.ITestService interface,
* generating a proxy if needed.
*/
public static com.hxiong.ITestService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.hxiong.ITestService))) {
return ((com.hxiong.ITestService)iin);
}
return new com.hxiong.ITestService.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_test:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.test(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.hxiong.ITestService
{
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 int test(int api) 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(api);
mRemote.transact(Stub.TRANSACTION_test, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_test = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int test(int api) throws android.os.RemoteException;
}
TestService.java
package com.hxiong;
import android.os.RemoteException;
public class TestService extends ITestService.Stub{
@Override
public int test(int api) throws RemoteException {
TODO
return 0;
}
}
红色框框的部分就是aidl帮我们生成的,对比前面C++层的binder 继承关系,可以看出它们十分相似(可以认为是一样的),java 层的Binder 对象C++层的BBinder,java层BinderProxy对应C++层的BpBinder,通过分析代码,看一下它们是怎么关联到一起的。
1、首先还是从获取binder proxy入手,Parcel的readStrongBinder()会得到IBinder
Parcel.java
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
android_os_parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
android_util_binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
//同一个进程中
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
// For the rest of the function we will hold this lock, to serialize
// looking/creation/destruction of Java proxies for native Binder proxies.
AutoMutex _l(mProxyLock);
// Someone else's... do we know about it?
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
jobject res = jniGetReferent(env, object);
if (res != NULL) {
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//这里创建了BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
// The proxy holds a reference to the native object.
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); //val 是C++层的BpBinder实例
val->incStrong((void*)javaObjectForIBinder);
// The native object needs to hold a weak reference back to the
// proxy, so we can retrieve the same proxy if it is still active.
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
// Also remember the death recipients registered on this proxy
sp drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get()));
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
} return object;
}
担心有些同学还看不明白,我简单描述一下,java层的BinderProxy对象是在jni中创建的,所以最终返回的是BinderProxy对象,C++层得到的BpBinder实例会保存在BinderProxy的mObject,可以简单的把mObject理解成指向C++层BpBinder实例的指针。
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); //val 是C++层的BpBinder实例
const char* const kBinderProxyPathName = "android/os/BinderProxy";
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf","Ljava/lang/ref/WeakReference;");
Binder.java
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
android_util_binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
...
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
...
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
...
return JNI_FALSE;
}
2、另外一边,作为binder的server端,我们看ITestService.Stub是怎么和BBinder关联起来的
binder.java
public Binder(){
init();
…
}
private nativefinal void init();
android_util_binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
class JavaBBinderHolder : public RefBase
{
public:
sp get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp mBinder;
};
class JavaBBinder : public BBinder{
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags =0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm%p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before =thread_state->getStrictModePolicy();
//printf("Transact from %p to Java code sending: ", this);
//data.print();
//printf("\n");
jbooleanres = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code,reinterpret_cast
…
// Need to always call through the native implementation of
// SYSPROPS_TRANSACTION.
if (code == SYSPROPS_TRANSACTION) {
BBinder::onTransact(code, data, reply, flags);
}
//aout << "onTransact to Java code; result=" < // << "Transact from" << this << " to Java code returning " // << reply <<": " << *reply << endl; return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; }
jboolean res =env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code,reinterpret_cast 最后,我们把上面的流程和相关联的模块绘制成结构图,前面写了那么多的文字,贴了那么多的代码,就是描述了下图。
前面的博客有讲到过,server端从binder driver读到数据后,会回调到BBinder::onTransact(),因为子类
JavaBBinder重写了onTransact(),所有会调用JavaBBinder 的onTransact(),红色标注的代码,就是jni call到java层的实现。