根據以前分析過的cpp代碼,以及編寫了JAVA層的代碼,筆者畫了一個圖進行了分層java
JAVA中,RPC層的代碼是直接經過aidl文件生成的,cpp部分是須要咱們本身編寫的android
那麼在JAVA中就存在兩個問題,就是圖中紅色的部分git
client是如何發送數據給server的
Service是如何讀取到數據,如何調用到onTransact函數的數組
經過這兩個問題去分析源碼,就能理解JAVA層的機制了cookie
既然咱們獲取服務使用 ServieManager 的getService,咱們就分析它(不知道爲何版本28這個類裏面的返回都是null,估計在哪裏作了什麼騷操做了吧)app
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
複製代碼
這個sCache就是一個HashMap
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
ide
主要看 getIServiceManager函數
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
複製代碼
public static final native IBinder getContextObject();
複製代碼
getContextObject 是一個native方法,之後看到這個native,咱們就應該知道,它是調用cpp的代碼,就是一個JNI調用過程測試
這部分主要是分析JNI的函數是如何生成的,不想了解的也能夠直接跳過ui
在Android系統開機過程當中,Zygote啓動時會有一個虛擬機註冊過程,該過程調用 AndroidRuntime::startReg 方法來完成jni方法的註冊(這部分分析來自gityuan)
在 AndroidRuntime.cpp 中
int AndroidRuntime::startReg(JNIEnv* env)
{
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
env->PushLocalFrame(200);
//註冊 gRegJNI是一個數組,記錄全部須要註冊的jni方法,其中有一項是REG_JNI(register_android_os_Binder)
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);
return 0;
}
複製代碼
看看 register_android_os_Binder
int register_android_os_Binder(JNIEnv* env) {
if (int_register_android_os_Binder(env) < 0)
return -1;
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
...
return 0;
}
複製代碼
看來須要一個一個看了
int_register_android_os_Binder 註冊 Binder類的jni方法
static int int_register_android_os_Binder(JNIEnv* env) {
//其中kBinderPathName = "android/os/Binder";查找kBinderPathName路徑所屬類
jclass clazz = FindClassOrDie(env, kBinderPathName);
//將Java層Binder類保存到mClass變量
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//將Java層execTransact()方法保存到mExecTransact變量;
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//將Java層mObject屬性保存到mObject變量
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
//註冊JNI方法
return RegisterMethodsOrDie(env, kBinderPathName, gBinderMethods,
NELEM(gBinderMethods));
}
複製代碼
gBinderOffsets 是什麼
static struct bindernative_offsets_t {
jclass mClass; //記錄Binder類
jmethodID mExecTransact; //記錄execTransact()方法
jfieldID mObject; //記錄mObject屬性
} gBinderOffsets;
複製代碼
gBinderOffsets保存了Binder.java類自己以及其成員方法execTransact()和成員屬性mObject,這爲JNI層訪問Java層提供通道。另外經過查詢獲取Java層 binder信息後保存到gBinderOffsets,而再也不須要每次查找binder類信息的方式能大幅度提升效率,是因爲每次查詢須要花費較多的CPU時間,尤爲是頻繁訪問時,但用額外的結構體來保存這些信息,是以空間換時間的方法
gBinderMethods
static const JNINativeMethod gBinderMethods[] = {
/* 名稱, 簽名, 函數指針 */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
複製代碼
經過RegisterMethodsOrDie(),將爲gBinderMethods數組中的方法創建了一一映射關係,從而爲Java層訪問JNI層提供通道
總之,int_register_android_os_Binder方法的主要功能:
android_util_Binder.cpp
static int int_register_android_os_BinderInternal(JNIEnv* env) {
//其中kBinderInternalPathName = "com/android/internal/os/BinderInternal"
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
複製代碼
註冊BinderInternal類的jni方法,gBinderInternalOffsets保存了BinderInternal的forceBinderGc()方法。
static const JNINativeMethod gBinderInternalMethods[] = {
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
複製代碼
android_util_Binder.cpp
static int int_register_android_os_BinderProxy(JNIEnv* env) {
//gErrorOffsets保存了Error類信息
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//gBinderProxyOffsets保存了BinderProxy類的信息
//其中kBinderProxyPathName = "android/os/BinderProxy"
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()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;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
//gClassOffsets保存了Class.getName()方法
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
複製代碼
static const JNINativeMethod gBinderProxyMethods[] = {
/* 名稱, 簽名, 函數指針 */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
複製代碼
這部份內容,讀者只要清楚這些JNI對應的函數,系統會在運行開始之初幫你作好這些工做就好了
/frameworks/base/core/jni/
找到 android_util_Binder.cpp(JNI的命名通常是 包名路徑_對應的JAVA函數名稱)
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) {
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
複製代碼
看到了熟悉的東西了沒,ProcessState::self()就是前面在cpp代碼時分析過的
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
複製代碼
它的handle是0,0是什麼,是service_manager,因此 ProcessState::self()->getContextObject(NULL) 返回的是一個 new BpBinder(0)
那麼接下來再看看 javaObjectForIBinder 是個什麼東西
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) {
......
//使用c代碼調用NewObject來建立JAVA BinderProxy對象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
//設置該對象的mObject = val.get = b = new BpBinder(0)
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
......
}
return object;
}
複製代碼
所以 ServiceManagerNative.asInterface 等價於
ServiceManagerNative.asInterface(new BinderProxy())
其中 BinderProxy的mObject指向new BpBinder(0)
接下來看 asInterface
static public IServiceManager asInterface(IBinder obj) {
//obj爲BpBinder
if (obj == null) {
return null;
}
//因爲obj爲BpBinder,該方法默認返回null
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
複製代碼
所以 ServiceManagerNative.asInterface 等價於
new ServiceManagerProxy(new BinderProxy())
看看ServiceManagerProxy的構造函數
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
複製代碼
mRemote爲 BinderProxy 對象,該BinderProxy對象對應於BpBinder(0)
其做爲binder代理端,指向native層的serviceManager
得知,getIServiceManager 就是獲取一個 ServiceManagerProxy對象
既然它是一個BpBinder,在咱們寫cpp代碼的時候,就應該知道它能幹什麼,註冊服務獲取服務等等
那麼,framework層從 ServieManager的getService 開始,ServiceManagerProxy爲本身的mRemote設置 BinderInternal.getContextObject() 從經過JNI方式返回的IBinder(指向service_manager)對象,後續經過 ServiceManagerProxy 來調用服務功能
獲取到服務的binder後,下一步就是使用服務了
咱們以前是這麼用的
IHelloService svr = IHelloService.Stub.asInterface(binder);
如今去找到aidl生成的文件,找到 asInterface
// 根據 IBinder 構建一個 IHelloService 在android的源碼中,這種使用方法很是常見
public static IHelloService asInterface(android.os.IBinder obj) {
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof IHelloService))) {
return ((IHelloService)iin);
}
return new IHelloService.Stub.Proxy(obj);
}
複製代碼
IHelloService.Stub.Proxy 是什麼,也是aidl爲咱們生成的
//客戶端的代理 是一個RPC過程,遠程調用服務端的方法
private static class Proxy implements IHelloService{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote){
mRemote = remote;
}
}
複製代碼
這樣就把Proxy中的mRemote賦值
而後就是調用服務中的方法了,以前咱們的代碼是svr.sayhello();
sayhello在Proxy中對應的函數方式代碼以下
@Override
public void sayhello() throws android.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();
}
}
複製代碼
那 mRemote.transact 是調用到哪裏去?
mRemote 分析過他是一個 JAVA 中的 BinderProxy 對象(8.0被抽出來了,8.0的源碼不少結構上都會有小小的變化,可能由於以前的代碼的可讀性確實比較差勁吧)
那麼找到 BinderProxy 的 transact 函數
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
......
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}
複製代碼
最終調用 transactNative ,又是native,那麼咱們就去源碼裏找
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) {
...
//java Parcel轉爲native Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
Parcel* reply = parcelForJavaObject(env, replyObj);
...
//在前面的分析過程當中咱們設置了gBinderProxyOffsets.mObject爲BpBinder,如今把這個BpBinder(0)取出來
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
//這個 target->transact 是 BpBinder::transact(),進入Binder驅動曾
status_t err = target->transact(code, *data, reply, flags);
...
return JNI_FALSE;
}
複製代碼
BpBinder::transact() 是否是很熟悉,cpp部分的源碼,忘記的話回頭看看cpp部分的分析,簡單說下
就是開個循環與server端進行通訊,接受server端返回的數據
到此爲止,client端就能夠發送它的數據,這裏是一個RPC遠程調用過程,咱們已經解決了第一個問題,client如何發送數據
接下來看第二個問題,Service是如何讀取到數據,如何調用到onTransact函數的
回頭看看AIDL爲咱們生成的代碼
case TRANSACTION_sayhello:
{
data.enforceInterface(DESCRIPTOR);
this.sayhello();
reply.writeNoException();
return true;
}
複製代碼
在服務端是調用 this.sayhello()
這個this 是什麼
@Override public android.os.IBinder asBinder() {
return this;
}
複製代碼
能夠得知他是一個IBinder,那麼這個IBinder具體是指什麼?
要分析server端的邏輯,就要從頭開始了
咱們編寫server端的時候並無本身寫循環,那麼他是怎麼處理的?顯然啊,確定是系統本身處理了
在哪處理的?實際上是使用app_process來啓動server進程的過程當中處理的
對於 AppRuntime 筆者不作過多分析,固然後續會有博文講解
源碼在 /frameworks/base/cmds/app_process/app_main.cpp 中
AppRuntime中有一個 onStarted() 函數
virtual void onStarted() {
sp<ProcessState> proc = ProcessState::self();
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
AndroidRuntime* ar = AndroidRuntime::getRuntime();
ar->callMain(mClassName, mClass, mArgC, mArgV);
if (ProcessState::self()->supportsProcesses()) {
IPCThreadState::self()->stopProcess();
}
}
複製代碼
注意到 proc->startThreadPool(),從名字應該能看出來,他是啓動一個線程池
這個 proc 是一個 ProcessState
ProcessState 是什麼還記得嗎?
表示進程的一個結構體,在cpp部分作過度析
startThreadPool 總不能也忘了吧,忘了回頭看看cpp的內部機制
proc->startThreadPool()
spawnPooledThread(true)
sp<Thread> t = new PoolThread(isMain)
t->run(name.string())
IPCThreadState::self()->joinThreadPool(mIsMain)
在 joinThreadPool 中就開始循環處理請求了,根據命令處理,若是是 BR_TRANSACTION 就會根據cookie 轉換爲 BBinder,並調用他的 transact,BBinder的transact其實就等價於他的 onTransact
到此,咱們解決了第二問題的一部分,也就是 server 是如何讀取到數據
那麼還剩最後一個問題,如何調用到onTransact函數的
既然BBinder的transact等價於他的 onTransact,那咱們看看AIDL生成的文件中,他的 IBinder 實際對象是否爲前面分析的 BBinder,若是是,整個流程就全通了
那就要從server端的開頭開始分析了
看看 addService 函數
public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
複製代碼
前面分析知道 getIServiceManager() 獲得的是一個 ServiceManagerProxy ,找到他的 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);
// code 是 ADD_SERVICE_TRANSACTION
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
複製代碼
重點在於 writeStrongBinder
public writeStrongBinder(IBinder val){
nativewriteStrongBinder(mNativePtr, val);
}
複製代碼
又是一個native,去找找他對應的函數,在 android_os_Parcel.cpp 中
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) {
//將java層Parcel轉換爲native層Parcel
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// .cookie = ibinderForJavaObject(env, object)獲得一個JavaBBinder對象
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
複製代碼
看看 ibinderForJavaObject 是什麼
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
//注意這個 obj 是傳進來的 service 對象
if (obj == NULL) return NULL;
//Java層的Binder對象
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//把一個Java對象(new XXXService()) 轉換爲cpp IBinder對象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
return NULL;
}
複製代碼
看看 JavaBBinderHolder 的 get,他返回的是一個 JavaBBinder
sp<JavaBBinder> get(JNIEnv* env, jobject obj) {
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
// 這是一個wp類型的,可能會被垃圾回收器給回收,因此每次使用前,都須要先判斷是否存在
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}
複製代碼
看下 JavaBBinder 的構造函數
class JavaBBinder : public BBinder
{
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
}
複製代碼
他是一個 BBinder,愈來愈接近咱們前面的猜測了
data.writeStrongBinder(service)最終等價於 parcel->writeStrongBinder(new JavaBBinder(env, obj));
obj = new XXXService() ,JavaBBinder的mObject = obj
parcel的writeStrongBinder是什麼?
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
複製代碼
看到 flatten_binder 應該熟悉了,根據IBinder構建 flat_binder_object ,而且把binder對象寫道cookie裏去,後續server才能經過cookie裏去讀取並使用
回到以前的調用,data.writeStrongBinder(service) 把數據進行一個轉換並放入data後
調用
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)
還記得這個mRmote是什麼嗎
咱們分析 IServiceManager 的時候
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
複製代碼
mRemote爲 BinderProxy 對象,該 BinderProxy 對象對應於BpBinder(0)
那麼找到 BinderProxy 的 transact 函數,其實前面已經分析過這部分了
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
......
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}
複製代碼
最終調用 transactNative ,又是native,那麼咱們就去源碼裏找
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) {
...
//java Parcel轉爲native Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
Parcel* reply = parcelForJavaObject(env, replyObj);
...
//在前面的分析過程當中咱們設置了gBinderProxyOffsets.mObject爲BpBinder,如今把這個BpBinder(0)取出來
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
//這個 target->transact 是 BpBinder::transact(),進入Binder驅動曾
status_t err = target->transact(code, *data, reply, flags);
...
return JNI_FALSE;
}
複製代碼
BpBinder::transact() cpp部分的源碼
開個循環與server端進行通訊,接受server端返回的數據,這裏咱們的client端是server,server端是service_manager
到此爲止,咱們只是分析了他如何註冊服務的,還沒獲得咱們第三個問題的答案
以前分析過,系統會幫咱們建立一個循環來擔任server端的循環處理工做,那麼在循環過程當中,會去讀取客戶端發送過來的消息,在分析cpp的代碼時,會在接收到數據後,取出 cookie 轉換爲 BBinder,並調用BBinder派生類的onTransact函數,咱們註冊服務的時候,BBinder的派生類是 JAVABBinder ,所以咱們只須要去找 JAVABBinder 的 onTransact 函數
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
JNIEnv* env = javavm_to_jnienv(mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int strict_policy_before = thread_state->getStrictModePolicy();
thread_state->setLastTransactionBinderFlags(flags);
//調用JAVA中的某個函數
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
jthrowable excep = env->ExceptionOccurred();
......
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
複製代碼
看 CallBooleanMethod 它到底調用的是JAVA裏的哪一個函數
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
複製代碼
mObject指向 XXXService對象
gBinderOffsets.mExecTransact指向: android/os/Binder類中的 execTransact 方法
那麼上面的 CallBooleanMethod 就是調用XXXService(派生自Binder)對象中的execTransact方法
那麼查找 execTransact,它是在AIDL爲咱們生成的文件中,Stub的父類,Binder裏面
private boolean execTransact(int code, long dataObj, long replyObj, int flags) {
BinderCallsStats binderCallsStats = BinderCallsStats.getInstance();
BinderCallsStats.CallSession callSession = binderCallsStats.callStarted(this, code);
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
boolean res;
final boolean tracingEnabled = Binder.isTracingEnabled();
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
......
} finally {
......
}
......
return res;
}
複製代碼
能夠發現,它調用的是 onTransact 函數,這個onTransact就是它的子類實現的 onTransact,它的子類就是AIDL爲咱們生成的 Stub 中,在咱們以前寫的測試代碼中是這樣的
@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_sayhello:
{
data.enforceInterface(DESCRIPTOR);
this.sayhello();
reply.writeNoException();
return true;
}
case TRANSACTION_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);
}
複製代碼
至此,咱們已經知道第三個問題的答案了,知道它是如何調用到JAVA層的onTransact函數
筆者完善了開頭的圖