Android在Native層實現了進程間的Binder通訊,可是上層應用程序的開發及Framework的實現都是Java,用Java層再實現一次確定是不合理的,Java能夠經過JNI調用Native Code,因此經過JNI複用Binder在Native層的實現就是一個瓜熟蒂落的事情。html
在Init進程的init2階段,系統啓動了ServerThread,在ServerThread中會啓動不少用Java實現的系統服務,好比說PowerService:java
power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power);
新建Server端實體,而後向ServiceManager註冊,從代碼表面看是和Native層Binder同樣的。PowerManagerService繼承自Java層的Binder類:android
public final class PowerManagerService extends IPowerManager.Stub public interface IPowerManager extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements android.os.IPowerManager {
因此在new PowerManagerService時會調用Binder的構造函數,Binder的構造函數中調用了init(),init是native方法,執行JNI的android_os_Binder_init:ide
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->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); }
在android_os_Binder_init,新建了一個JavaBBinderHolder對角,並將其指針保存在了obj即Binder的gBinderOffsets.mObject域中,而gBinderOffsets.mObject又是個什麼東西?看一下它的定義:函數
static struct bindernative_offsets_t { jclass mClass; jmethodID mExecTransact; jfieldID mObject; } gBinderOffsets;
在AndroidRuntine::startReg中會調用register_android_os_Binder,register_android_os_Binder會調用int_register_android_os_Binder等函數創建Java層Binder、BinderProxy、BinderInternal、Log等與Native層的映射關係。好比在int_register_android_os_Binder中會經過JNI標準的方法GetMethodID等初始化gBinderOffsets:fetch
static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBinderPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }
在android_os_Binder_init中new了一個JavaBBinderHolder,JavaBBinderHolder new了一個JavaBBinder保存到了本身的成員wp<JavaBBinder> mBinder中。ui
JavaBBinder繼承自Native層的BBinder,而且將Java層的Binder對象(此處即PowerManagerService)保存到了成員mObject中,並經過object()方法返回。this
如今咱們發現,JavaBinder,BinderBBinderHolder,JavaBBinder存在相互引用關係:spa
Binder是一種Client-Server類型的IPC,PowerManagerService屬於Server端,從Native Binder中咱們知道,Client經過BpBinder經由Binder Driver、BBinder與Serverr通訊,PowerManagerService經過JavaBBinderHolder引用JavaBBinder,而JavaBBinder繼承自BBinder,符合了Server的條件,Server實體有了,接下來就要向ServiceManager註冊,經過如下方法:代理
ServiceManager.addService(Context.POWER_SERVICE,power);
// In ServiceManager public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
BinderInternal.getContextObject是一個Native方法,調用JNIandroid_os_BinderInternal_getContextObject:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
ProcessState::self()->getContextObject就很熟悉了,在Binder in Native中能夠知道,這個調用返回new BpBinder(0)。
javaObjectForIBinder的做用就是,新建一個Java層的BinderProxy對象,將Native層的BpBinder保存到BinderProxy.mObject,並將BinderProxy的弱引用經過attachObject保存到Native層的BpBinder(成員mObjects中),這樣Java層的BinderProxy與Native層的BpBinder就能夠相互引用了。Java層的BinderProxy及其在Native層的表示間的映射關係同Binder類同樣也是在register_android_os_Binder中創建的。
上面紅色的部分就等效於:
gServiceManager = ServiceManagerNative.asInterface(new BinderProxy());
ServiceManagerNative繼承自IServiceManager與Java層的Binder類,BinderProxy能夠引用BpBinder。asInterface就像Native Binder中的interface_cast的,asInterface實現能夠簡化爲:
return new ServiceManagerProxy(obj);
obj是BinderProxy對象。ServiceManagerProxy直接將這個BinderProxy對象保存在了成員mRemote中,並經過asBinder返回。
ServiceManagerProxy同時實現了IServiceManager,並且由其名字可知,ServiceManagerProxy是做爲ServiceManager在Client端的代理的,看下它的addService的實現:
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
writeStrongBinder是Native方法,調用android_os_Parcel_writeStrongBinder,在android_os_Parcel_writeStrongBinder將Java Parcel轉換成Native Parcel(Native Parcel的指針保存在Java Parcel的成員變量中),而後調用如下語句:
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)根據obj返回JavaBBinder或Native BpBinder,在這裏傳入的obj 是PowerManagerService,返回JavaBBinder。接下來調用了mRemote.transact,mRemote是BinderProxy的對象。
BinderProxy的transact是Native方法,調用JNIandroid_os_BinderProxy_transact,在android_os_BinderProxy_transact中經過:
IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
...
status_t err = target->transact(code, *data, reply, flags);
獲取到BinderProxy中保存的BpBinder,而後調用BpBinder的transact,到這裏就和Native Binder的調用流程同樣了,Native ServiceManager會註冊咱們的Service,在這裏是PowerManagerService。
Service已經向ServiceManager註冊了,那麼咱們怎麼得到所註冊的Service,或者更準確地說,怎麼得到所註冊的Service的代理呢?
回想下咱們在APK中是怎麼獲取系統服務的:
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
看一下getSystemService的實現,位於ContextImpl中:
@Override public Object getSystemService(String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this); } registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler()); }});
1. ServiceManager.getService得到IBinder對象
同ServiceManager.addService同樣,ServiceManager.getService首先得到一個ServiceManagerProxy的對象,而後調用它的getService方法:
public IBinder getService(String name) throws RemoteException { ... mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); IBinder binder = reply.readStrongBinder(); ... return binder; }
mRemote是BinderProxy對象,內部引用了BpBinder,調用BinderProxy的Native方法transact與Binder通訊,而後經過readStrongBinder()讀取返回的數據,一個IBinder對象。
readStrongBinder中經過javaObjectForIBinder返回了BinderProxy對象,前面已經說過。
2. 經過asInterface將得到的IBinder對象轉換成IPowerManager對象
IPowerManager.Stub.asInterface能夠簡化爲:
return new android.os.IPowerManager.Stub.Proxy(obj);
Proxy只是將傳入的參數(BinderProxy)保存到了成員mRemote中並經過asBinder返回。
Proxy與Stub都是IPowerManager.aidl編譯後生成的類,都位於IPowerManager.java中。關於aidl網上有不少資料。
3. IPowerManager對象是不向外暴露的,構造一個PowerManager封裝IPowerManager返回。
PowerManager只是將IPowerManager保存在了成員變量中,PowerManager中保存了BinderProxy,BinderProxy中引用了Native BpBinder,就能夠與Server進行通訊了。
Server端接收到Client的請求後會調用BBinder的transact處理請求,transact會調用虛函數onTransact,JavaBBinder繼承自BBinder,因此會調用JavaBBinder::onTransact,在JavaBBinder::onTransact中有如下一句:
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)reply, flags);
經過JNI反向調用了Java類的方法。前面咱們知道了,Java實現的Service中,Service對象,JavaBBinderHolder,JavaBBinder存在相互引用關係,JavaBBinder的成員mObject引用了Java中的Service對象,好比此處的PowerManagerService,並且在int_register_android_os_Binder中經過
gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
將Service的execTransact方法(實際上是Binder的方法)保存在了gBinderOffsets.mExecTransact中,所在以JavaBBinder::onTransact中會調用Binder.execTransact。在Binder.execTransact中調用了onTransact,執行子類即Stub類的onTransact方法,在onTransact中根據code值執行相應的方法,最終是調用Service類(繼承自Stub)中相應的方法。
Java層經過JNI利用了Native層的Binder,在JNI函數註冊時會創建Java層Binder,BinderProxy,BinderInternal等類與Native層的映射關係。Java層Service實體繼承自Java層的Binder類,在Binder類初始化時會建立一個JavaBBinderHolder做爲JavaBBinder的容器,JavaBBinder繼承自BBinder,Java層Binder類引用JavaBBinderHolder,JavaBBinderHolder引用JavaBBinder,JavaBBinder繼承自BBinder並引用Java層的Binder類,這三者互相引用,這樣Java層的Service實體就能夠經過BBinder與驅動進行通訊了。
進程向Java層的ServiceManager代理髮送GET_SERVICE請求,而後經過JNI向Native層的ServiceManager請求服務,Native層的ServiceManager返回請求的服務的代理對象BpBinder,經過javaObjectForIBinder函數將Native的BpBinder轉化爲Java層對應的BinderProxy,而後經過aidl生成的Stub類asInterface方法將BinderProxy封閉到請求的服務的代理對象中,這個代理對象引用了BinderProxy,BinderProxy內部保存了Native層的BpBinder,這樣就能夠與驅動進行通訊了。
當Server端接收到Client的請求時會經過BBinder的transact調用Server的服務,BBinder的transact調用虛函數onTransact,這樣就會調到BBinder的子類JavaBBinder的onTransact,而JavaBinder::onTransact會經過JNI反向調用到Java層Binder類的execTransact,Binder.execTransact調用onTransact即子類Stub的onTransact,而後根據code值調用Service實體類(繼承自Stub)相應的方法。