Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析
在前面幾篇文章中,我們?cè)敿?xì)介紹了Android系統(tǒng)進(jìn)程間通信機(jī)制Binder的原理,并且深入分析了系統(tǒng)提供的Binder運(yùn)行庫和驅(qū)動(dòng)程序的源代碼。細(xì)心的讀者會(huì)發(fā)現(xiàn),這幾篇文章分析的Binder接口都是基于C/C++語言來實(shí)現(xiàn)的,但是我們?cè)诰帉憫?yīng)用程序都是基于Java語言的,那么,我們?nèi)绾问褂肑ava語言來使用系統(tǒng)的Binder機(jī)制來進(jìn)行進(jìn)程間通信呢?這就是本文要介紹的Android系統(tǒng)應(yīng)用程序框架層的用Java語言來實(shí)現(xiàn)的Binder接口了。
熟悉Android系統(tǒng)的讀者,應(yīng)該能想到應(yīng)用程序框架中的基于Java語言的Binder接口是通過JNI來調(diào)用基于C/C++語言的Binder運(yùn)行庫來為Java應(yīng)用程序提供進(jìn)程間通信服務(wù)的了。JNI在Android系統(tǒng)中用得相當(dāng)普遍,SDK中的Java接口API很多只是簡(jiǎn)單地通過JNI來調(diào)用底層的C/C++運(yùn)行庫從而為應(yīng)用程序服務(wù)的。
這里,我們?nèi)匀皇峭ㄟ^具體的例子來說明Binder機(jī)制在應(yīng)用程序框架層中的Java接口,主要就是Service Manager、Server和Client這三個(gè)角色的實(shí)現(xiàn)了。通常,在應(yīng)用程序中,我們都是把Server實(shí)現(xiàn)為Service的形式,并且通過IServiceManager.addService接口來把這個(gè)Service添加到Service Manager,Client也是通過IServiceManager.getService接口來獲得Service接口,接著就可以使用這個(gè)Service提供的功能了,這個(gè)與運(yùn)行時(shí)庫的Binder接口是一致的。
前面我們學(xué)習(xí)Android硬件抽象層時(shí),曾經(jīng)在應(yīng)用程序框架層中提供了一個(gè)硬件訪問服務(wù)HelloService,這個(gè)Service運(yùn)行在一個(gè)獨(dú)立的進(jìn)程中充當(dāng)Server的角色,使用這個(gè)Service的Client運(yùn)行在另一個(gè)進(jìn)程中,它們之間就是通過Binder機(jī)制來通信的了。這里,我們就使用HelloService這個(gè)例子來分析Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼。所以希望讀者在閱讀下面的內(nèi)容之前,先了解一下前面在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問服務(wù)這篇文章。
這篇文章通過五個(gè)情景來學(xué)習(xí)Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口:1. 獲取Service Manager的Java遠(yuǎn)程接口的過程;2. HelloService接口的定義;3. HelloService的啟動(dòng)過程;4. Client獲取HelloService的Java遠(yuǎn)程接口的過程;5. Client通過HelloService的Java遠(yuǎn)程接口來使用HelloService提供的服務(wù)的過程。
一. 獲取Service Manager的Java遠(yuǎn)程接口
我們要獲取的Service Manager的Java遠(yuǎn)程接口是一個(gè)ServiceManagerProxy對(duì)象的IServiceManager接口。我們現(xiàn)在就來看看ServiceManagerProxy類是長(zhǎng)什么樣子的:

這里可以看出,ServiceManagerProxy類實(shí)現(xiàn)了IServiceManager接口,IServiceManager提供了getService和addService兩個(gè)成員函數(shù)來管理系統(tǒng)中的Service。從ServiceManagerProxy類的構(gòu)造函數(shù)可以看出,它需要一個(gè)BinderProxy對(duì)象的IBinder接口來作為參數(shù)。因此,要獲取Service Manager的Java遠(yuǎn)程接口ServiceManagerProxy,首先要有一個(gè)BinderProxy對(duì)象。下面將會(huì)看到這個(gè)BinderProxy對(duì)象是如何獲得的。
再來看一下是通過什么路徑來獲取Service Manager的Java遠(yuǎn)程接口ServiceManagerProxy的。這個(gè)主角就是ServiceManager了,我們也先看一下ServiceManager是長(zhǎng)什么樣子的:

ServiceManager類有一個(gè)靜態(tài)成員函數(shù)getIServiceManager,它的作用就是用來獲取Service Manager的Java遠(yuǎn)程接口了,而這個(gè)函數(shù)又是通過ServiceManagerNative來獲取Service Manager的Java遠(yuǎn)程接口的。
接下來,我們就看一下ServiceManager.getIServiceManager這個(gè)函數(shù)的實(shí)現(xiàn),這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/ServiceManager.java文件中:
public final class ServiceManager {
......
private static IServiceManager sServiceManager;
......
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
......
}
如果其靜態(tài)成員變量sServiceManager尚未創(chuàng)建,那么就調(diào)用ServiceManagerNative.asInterface函數(shù)來創(chuàng)建。在調(diào)用ServiceManagerNative.asInterface函數(shù)之前,首先要通過BinderInternal.getContextObject函數(shù)來獲得一個(gè)BinderProxy對(duì)象。
我們來看一下BinderInternal.getContextObject的實(shí)現(xiàn),這個(gè)函數(shù)定義在frameworks/base/core/java/com/android/internal/os/BinderInternal.java文件中:
public class BinderInternal {
......
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
......
}
這里可以看出,BinderInternal.getContextObject是一個(gè)JNI方法,它實(shí)現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
這里看到我們熟悉的ProcessState::self()->getContextObject函數(shù),具體可以參考淺談Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server和Client獲得Service Manager接口之路一文。ProcessState::self()->getContextObject函數(shù)返回一個(gè)BpBinder對(duì)象,它的句柄值是0,即下面語句:
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
相當(dāng)于是:
sp<IBinder> b = new BpBinder(0);
接著調(diào)用javaObjectForIBinder把這個(gè)BpBinder對(duì)象轉(zhuǎn)換成一個(gè)BinderProxy對(duì)象:
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
//printf("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 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 = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
if (res != NULL) {
LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
return res;
}
LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
LOGV("objectForBinder %p: created new %p!\n", val.get(), object);
// The proxy holds a reference to the native object.
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
val->incStrong(object);
// 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);
// Note that a new object reference has been created.
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}
在介紹這個(gè)函數(shù)之前,先來看兩個(gè)變量gBinderOffsets和gBinderProxyOffsets的定義。
先看gBinderOffsets的定義:
static struct bindernative_offsets_t
{
// Class state.
jclass mClass;
jmethodID mExecTransact;
// Object state.
jfieldID mObject;
} gBinderOffsets;
簡(jiǎn)單來說,gBinderOffsets變量是用來記錄上面第二個(gè)類圖中的Binder類的相關(guān)信息的,它是在注冊(cè)Binder類的JNI方法的int_register_android_os_Binder函數(shù)初始化的:
const char* const kBinderPathName = "android/os/Binder";
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));
}
再來看gBinderProxyOffsets的定義:
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mConstructor;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mObject;
jfieldID mSelf;
} gBinderProxyOffsets;
簡(jiǎn)單來說,gBinderProxyOffsets是用來變量是用來記錄上面第一個(gè)圖中的BinderProxy類的相關(guān)信息的,它是在注冊(cè)BinderProxy類的JNI方法的int_register_android_os_BinderProxy函數(shù)初始化的:
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz;
clazz = env->FindClass("java/lang/ref/WeakReference");
LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference");
gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gWeakReferenceOffsets.mGet
= env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
assert(gWeakReferenceOffsets.mGet);
clazz = env->FindClass("java/lang/Error");
LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error");
gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
clazz = env->FindClass(kBinderProxyPathName);
LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy");
gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
gBinderProxyOffsets.mConstructor
= env->GetMethodID(clazz, "<init>", "()V");
assert(gBinderProxyOffsets.mConstructor);
gBinderProxyOffsets.mSendDeathNotice
= env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
assert(gBinderProxyOffsets.mSendDeathNotice);
gBinderProxyOffsets.mObject
= env->GetFieldID(clazz, "mObject", "I");
assert(gBinderProxyOffsets.mObject);
gBinderProxyOffsets.mSelf
= env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
assert(gBinderProxyOffsets.mSelf);
return AndroidRuntime::registerNativeMethods(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
回到前面的javaObjectForIBinder函數(shù)中,下面這段代碼:
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast<JavaBBinder*>(val.get())->object();
//printf("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
前面說過,這里傳進(jìn)來的參數(shù)是一個(gè)BpBinder的指針,而BpBinder::checkSubclass繼承于父類IBinder::checkSubclass,它什么也不做就返回false。
于是函數(shù)繼續(xù)往下執(zhí)行:
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
由于這個(gè)BpBinder對(duì)象是第一創(chuàng)建,它里面什么對(duì)象也沒有,因此,這里返回的object為NULL。
于是函數(shù)又繼續(xù)往下執(zhí)行:
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
這里,就創(chuàng)建了一個(gè)BinderProxy對(duì)象了。創(chuàng)建了之后,要把這個(gè)BpBinder對(duì)象和這個(gè)BinderProxy對(duì)象關(guān)聯(lián)起來:
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
就是通過BinderProxy.mObject成員變量來關(guān)聯(lián)的了,BinderProxy.mObject成員變量記錄了這個(gè)BpBinder對(duì)象的地址。
接下去,還要把它放到BpBinder里面去,下次就要使用時(shí),就可以在上一步調(diào)用BpBinder::findObj把它找回來了:
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
最后,就把這個(gè)BinderProxy返回到android_os_BinderInternal_getContextObject函數(shù),最終返回到最開始的ServiceManager.getIServiceManager函數(shù)中來了,于是,我們就獲得一個(gè)BinderProxy對(duì)象了。
回到ServiceManager.getIServiceManager中,從下面語句返回:
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
相當(dāng)于是:
sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());
接下去就是調(diào)用ServiceManagerNative.asInterface函數(shù)了,這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/ServiceManagerNative.java文件中:
public abstract class ServiceManagerNative ......
{
......
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
......
}
這里的參數(shù)obj是一個(gè)BinderProxy對(duì)象,它的queryLocalInterface函數(shù)返回null。因此,最終以這個(gè)BinderProxy對(duì)象為參數(shù)創(chuàng)建一個(gè)ServiceManagerProxy對(duì)象。
返回到ServiceManager.getIServiceManager中,從下面語句返回:
sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());
就相當(dāng)于是:
sServiceManager = new ServiceManagerProxy(new BinderProxy());
于是,我們的目標(biāo)終于完成了。
總結(jié)一下,就是在Java層,我們擁有了一個(gè)Service Manager遠(yuǎn)程接口ServiceManagerProxy,而這個(gè)ServiceManagerProxy對(duì)象在JNI層有一個(gè)句柄值為0的BpBinder對(duì)象與之通過gBinderProxyOffsets關(guān)聯(lián)起來。
這樣獲取Service Manager的Java遠(yuǎn)程接口的過程就完成了。
二. HelloService接口的定義
前面我們?cè)趯W(xué)習(xí)Android系統(tǒng)的硬件抽象層(HAL)時(shí),在在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問服務(wù)這篇文章中,我們編寫了一個(gè)硬件服務(wù)HelloService,它的服務(wù)接口定義在frameworks/base/core/java/android/os/IHelloService.aidl文件中:
package android.os;
interface IHelloService
{
void setVal(int val);
int getVal();
}
這個(gè)服務(wù)接口很簡(jiǎn)單,只有兩個(gè)函數(shù),分別用來讀寫硬件寄存器。
注意,這是一個(gè)aidl文件,編譯后會(huì)生成一個(gè)IHelloService.java。我們來看一下這個(gè)文件的內(nèi)容隱藏著什么奧秘,可以這么神奇地支持進(jìn)程間通信。
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/IHelloService.aidl
*/
package android.os;
public interface IHelloService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService
{
private static final java.lang.String DESCRIPTOR = "android.os.IHelloService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.IHelloService interface,
* generating a proxy if needed.
*/
public static android.os.IHelloService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IHelloService))) {
return ((android.os.IHelloService)iin);
}
return new android.os.IHelloService.Stub.Proxy(obj);
}
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_setVal:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
this.setVal(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getVal:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.getVal();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.IHelloService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public void setVal(int val) 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.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setVal, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public int getVal() 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);
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void setVal(int val) throws android.os.RemoteException;
public int getVal() throws android.os.RemoteException;
}
這里我們可以看到IHelloService.aidl這個(gè)文件編譯后的真面目,原來就是根據(jù)IHelloService接口的定義生成相應(yīng)的Stub和Proxy類,這個(gè)就是我們熟悉的Binder機(jī)制的內(nèi)容了,即實(shí)現(xiàn)這個(gè)HelloService的Server必須繼續(xù)于這里的IHelloService.Stub類,而這個(gè)HelloService的遠(yuǎn)程接口就是這里的IHelloService.Stub.Proxy對(duì)象獲得的IHelloService接口。接下來的內(nèi)容,我們就可以看到IHelloService.Stub和IHelloService.Stub.Proxy是怎么創(chuàng)建或者使用的。
三. HelloService的啟動(dòng)過程
在討論HelloService的啟動(dòng)過程之前,我們先來看一下實(shí)現(xiàn)HelloService接口的Server是怎么定義的。
回憶在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問服務(wù)一文,我們?cè)趂rameworks/base/services/java/com/android/server目錄下新增了一個(gè)HelloService.java文件:
package com.android.server;
import android.content.Context;
import android.os.IHelloService;
import android.util.Slog;
public class HelloService extends IHelloService.Stub {
private static final String TAG = "HelloService";
HelloService() {
init_native();
}
public void setVal(int val) {
setVal_native(val);
}
public int getVal() {
return getVal_native();
}
private static native boolean init_native();
private static native void setVal_native(int val);
private static native int getVal_native();
}
這里,我們可以看到,HelloService繼續(xù)了IHelloService.Stub類,它通過本地方法調(diào)用實(shí)現(xiàn)了getVal和setVal兩個(gè)函數(shù)。我們不關(guān)心這兩個(gè)函數(shù)的具體實(shí)現(xiàn),有興趣的讀者可以參考在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問服務(wù)一文。
有了HelloService這個(gè)Server類后,下一步就是考慮怎么樣把它啟動(dòng)起來了。在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定義了SystemServer類。SystemServer對(duì)象是在系統(tǒng)啟動(dòng)的時(shí)候創(chuàng)建的,它被創(chuàng)建的時(shí)候會(huì)啟動(dòng)一個(gè)線程來創(chuàng)建HelloService,并且把它添加到Service Manager中去。
我們來看一下這部份的代碼:
class ServerThread extends Thread {
......
@Override
public void run() {
......
Looper.prepare();
......
try {
Slog.i(TAG, "Hello Service");
ServiceManager.addService("hello", new HelloService());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Hello Service", e);
}
......
Looper.loop();
......
}
}
......
public class SystemServer
{
......
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
......
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
......
}
這里,我們可以看到,在ServerThread.run函數(shù)中,執(zhí)行了下面代碼把HelloService添加到Service Manager中去。這里我們關(guān)注把HelloService添加到Service Manager中去的代碼:
try {
Slog.i(TAG, "Hello Service");
ServiceManager.addService("hello", new HelloService());
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Hello Service", e);
}
通過調(diào)用ServiceManager.addService把一個(gè)HelloService實(shí)例添加到Service Manager中去。
我們先來看一下HelloService的創(chuàng)建過程:
new HelloService();
這個(gè)語句會(huì)調(diào)用HelloService類的構(gòu)造函數(shù),而HelloService類繼承于IHelloService.Stub類,IHelloService.Stub類又繼承了Binder類,因此,最后會(huì)調(diào)用Binder類的構(gòu)造函數(shù):
public class Binder implements IBinder {
......
private int mObject;
......
public Binder() {
init();
......
}
private native final void init();
......
}
這里調(diào)用了一個(gè)JNI方法init來初始化這個(gè)Binder對(duì)象,這個(gè)JNI方法定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static void android_os_Binder_init(JNIEnv* env, jobject clazz)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz);
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh);
jbh->incStrong(clazz);
env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh);
}
它實(shí)際上只做了一件事情,就是創(chuàng)建一個(gè)JavaBBinderHolder對(duì)象jbh,然后把這個(gè)對(duì)象的地址保存在上面的Binder類的mObject成員變量中,后面我們會(huì)用到。
回到ServerThread.run函數(shù)中,我們?cè)賮砜匆幌耂erviceManager.addService函數(shù)的實(shí)現(xiàn):
public final class ServiceManager {
......
private static IServiceManager sServiceManager;
......
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
......
}
這里的getIServiceManager函數(shù)我們?cè)谇懊嬉呀?jīng)分析過了,它返回的是一個(gè)ServiceManagerProxy對(duì)象的IServiceManager接口。因此,我們進(jìn)入到ServiceManagerProxy.addService中去看看:
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
......
public void addService(String name, IBinder service)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
......
private IBinder mRemote;
}
這里的Parcel類是用Java來實(shí)現(xiàn)的,它跟我們前面幾篇文章介紹Binder機(jī)制時(shí)提到的用C++實(shí)現(xiàn)的Parcel類的作用是一樣的,即用來在兩個(gè)進(jìn)程之間傳遞數(shù)據(jù)。
這里我們關(guān)注是如何把參數(shù)service寫到data這個(gè)Parcel對(duì)象中去的:
data.writeStrongBinder(service);
我們來看看Parcel.writeStrongBinder函數(shù)的實(shí)現(xiàn):
public final class Parcel {
......
/**
* Write an object into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
public final native void writeStrongBinder(IBinder val);
......
}
這里的writeStrongBinder函數(shù)又是一個(gè)JNI方法,它定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
}
}
}
這里的clazz參數(shù)是一個(gè)Java語言實(shí)現(xiàn)的Parcel對(duì)象,通過parcelForJavaObject把它轉(zhuǎn)換成C++語言實(shí)現(xiàn)的Parcel對(duì)象。這個(gè)函數(shù)的實(shí)現(xiàn)我們就不看了,有興趣的讀者可以研究一下,這個(gè)函數(shù)也是實(shí)現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp這個(gè)文件中。
這里的object參數(shù)是一個(gè)Java語言實(shí)現(xiàn)的Binder對(duì)象,在調(diào)用C++語言實(shí)現(xiàn)的Parcel::writeStrongBinder把這個(gè)對(duì)象寫入到parcel對(duì)象時(shí),首先通過ibinderForJavaObject函數(shù)把這個(gè)Java語言實(shí)現(xiàn)的Binder對(duì)象轉(zhuǎn)換為C++語言實(shí)現(xiàn)的JavaBBinderHolder對(duì)象:
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env) : NULL;
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
}
LOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
我們知道,這里的obj參數(shù)是一個(gè)Binder類的實(shí)例,因此,這里會(huì)進(jìn)入到第一個(gè)if語句中去。
在前面創(chuàng)建HelloService對(duì)象,曾經(jīng)在調(diào)用到HelloService的父類Binder中,曾經(jīng)在JNI層創(chuàng)建了一個(gè)JavaBBinderHolder對(duì)象,然后把這個(gè)對(duì)象的地址保存在Binder類的mObject成員變量中,因此,這里把obj對(duì)象的mObject成員變量強(qiáng)制轉(zhuǎn)為JavaBBinderHolder對(duì)象。
到了這里,這個(gè)函數(shù)的功課還未完成,還剩下最后關(guān)鍵的一步:
return jbh != NULL ? jbh->get(env) : NULL;
這里就是jbh->get這個(gè)語句了。
在JavaBBinderHolder類中,有一個(gè)成員變量mBinder,它的類型為JavaBBinder,而JavaBBinder類繼承于BBinder類。在前面學(xué)習(xí)Binder機(jī)制的C++語言實(shí)現(xiàn)時(shí),我們?cè)贏ndroid系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過程源代碼分析這篇文章中,曾經(jīng)介紹過,IPCThreadState類負(fù)責(zé)與Binder驅(qū)動(dòng)程序進(jìn)行交互,它把從Binder驅(qū)動(dòng)程序讀出來的請(qǐng)求作簡(jiǎn)單的處理后,最后把這個(gè)請(qǐng)求扔給BBinder的onTransact函數(shù)來進(jìn)一步處理。
這里,我們就是要把JavaBBinderHolder里面的JavaBBinder類型Binder實(shí)體添加到Service Manager中去,以便使得這個(gè)HelloService有Client來請(qǐng)求服務(wù)時(shí),由Binder驅(qū)動(dòng)程序來喚醒這個(gè)Server線程,進(jìn)而調(diào)用這個(gè)JavaBBinder類型Binder實(shí)體的onTransact函數(shù)來進(jìn)一步處理,這個(gè)函數(shù)我們?cè)诤竺鏁?huì)繼續(xù)介紹。
先來看一下JavaBBinderHolder::get函數(shù)的實(shí)現(xiàn):
class JavaBBinderHolder : public RefBase
{
......
JavaBBinderHolder(JNIEnv* env, jobject object)
: mObject(object)
{
......
}
......
sp<JavaBBinder> get(JNIEnv* env)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, mObject);
mBinder = b;
......
}
return b;
}
......
jobject mObject;
wp<JavaBBinder> mBinder;
};
這里是第一次調(diào)用get函數(shù),因此,會(huì)創(chuàng)建一個(gè)JavaBBinder對(duì)象,并且保存在mBinder成員變量中。注意,這里的mObject就是上面創(chuàng)建的HelloService對(duì)象了,這是一個(gè)Java對(duì)象。這個(gè)HelloService對(duì)象最終也會(huì)保存在JavaBBinder對(duì)象的成員變量mObject中。
回到android_os_Parcel_writeStrongBinder函數(shù)中,下面這個(gè)語句:
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
相當(dāng)于是:
const status_t err = parcel->writeStrongBinder((JavaBBinderHodler*)(obj.mObject));
因此,這里的效果相當(dāng)于是寫入了一個(gè)JavaBBinder類型的Binder實(shí)體到parcel中去。這與我們前面介紹的Binder機(jī)制的C++實(shí)現(xiàn)是一致的。
接著,再回到ServiceManagerProxy.addService這個(gè)函數(shù)中,最后它通過其成員變量mRemote來執(zhí)行進(jìn)程間通信操作。前面我們?cè)诮榻B如何獲取Service Manager遠(yuǎn)程接口時(shí)提到,這里的mRemote成員變量實(shí)際上是一個(gè)BinderProxy對(duì)象,因此,我們?cè)賮砜纯碆inderProxy.transact函數(shù)的實(shí)現(xiàn):
final class BinderProxy implements IBinder {
......
public native boolean transact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
......
}
這里的transact成員函數(shù)又是一個(gè)JNI方法,它定義在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj,
jobject replyObj, jint flags)
{
......
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
IBinder* target = (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
......
status_t err = target->transact(code, *data, reply, flags);
......
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err);
return JNI_FALSE;
}
這里傳進(jìn)來的參數(shù)dataObj和replyObj是一個(gè)Java接口實(shí)現(xiàn)的Parcel類,由于這里是JNI層,需要把它轉(zhuǎn)換為C++實(shí)現(xiàn)的Parcel類,它們就是通過我們前面說的parcelForJavaObject函數(shù)進(jìn)行轉(zhuǎn)換的。
前面我們?cè)诜治鋈绾潍@取Service Manager遠(yuǎn)程接口時(shí),曾經(jīng)說到,在JNI層中,創(chuàng)建了一個(gè)BpBinder對(duì)象,它的句柄值為0,它的地址保存在gBinderProxyOffsets.mObject中,因此,這里通過下面語句得到這個(gè)BpBinder對(duì)象的IBinder接口:
IBinder* target = (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
有了這個(gè)IBinder接口后,就和我們前面幾篇文章介紹Binder機(jī)制的C/C++實(shí)現(xiàn)一致了。
最后,通過BpBinder::transact函數(shù)進(jìn)入到Binder驅(qū)動(dòng)程序,然后Binder驅(qū)動(dòng)程序喚醒Service Manager響應(yīng)這個(gè)ADD_SERVICE_TRANSACTION請(qǐng)求:
status_t err = target->transact(code, *data, reply, flags);
具體可以參考Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過程源代碼分析一文。需要注意的是,這里的data包含了一個(gè)JavaBBinderHolder類型的Binder實(shí)體對(duì)象,它就代表了我們上面創(chuàng)建的HelloService。Service Manager收到這個(gè)ADD_SERVICE_TRANSACTION請(qǐng)求時(shí),就會(huì)把這個(gè)Binder實(shí)體納入到自己內(nèi)部進(jìn)行管理。
這樣,實(shí)現(xiàn)HelloService的Server的啟動(dòng)過程就完成了。
四. Client獲取HelloService的Java遠(yuǎn)程接口的過程
前面我們?cè)趯W(xué)習(xí)Android系統(tǒng)硬件抽象層(HAL)時(shí),在在Ubuntu上為Android系統(tǒng)內(nèi)置Java應(yīng)用程序測(cè)試Application Frameworks層的硬件服務(wù)這篇文章中,我們創(chuàng)建了一個(gè)應(yīng)用程序,這個(gè)應(yīng)用程序作為一個(gè)Client角色,借助Service Manager這個(gè)Java遠(yuǎn)程接口來獲得HelloService的遠(yuǎn)程接口,進(jìn)而調(diào)用HelloService提供的服務(wù)。
我們看看它是如何借助Service Manager這個(gè)Java遠(yuǎn)程接口來獲得HelloService的遠(yuǎn)程接口的。在Hello這個(gè)Activity的onCreate函數(shù),通過IServiceManager.getService函數(shù)來獲得HelloService的遠(yuǎn)程接口:
public class Hello extends Activity implements OnClickListener {
......
private IHelloService helloService = null;
......
@Override
public void onCreate(Bundle savedInstanceState) {
helloService = IHelloService.Stub.asInterface(
ServiceManager.getService("hello"));
}
......
}
我們先來看ServiceManager.getService的實(shí)現(xiàn)。前面我們說過,這里實(shí)際上是調(diào)用了ServiceManagerProxy.getService函數(shù):
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
......
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
......
private IBinder mRemote;
}
最終通過mRemote.transact來執(zhí)行實(shí)際操作。我們?cè)谇懊嬉呀?jīng)介紹過了,這里的mRemote實(shí)際上是一個(gè)BinderProxy對(duì)象,它的transact成員函數(shù)是一個(gè)JNI方法,實(shí)現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中的android_os_BinderProxy_transact函數(shù)中。
這個(gè)函數(shù)前面我們已經(jīng)看到了,這里就不再列出來了。不過,當(dāng)這個(gè)函數(shù)從:
status_t err = target->transact(code, *data, reply, flags);
這里的reply變量里面就包括了一個(gè)HelloService的引用了。注意,這里的reply變量就是我們?cè)赟erviceManagerProxy.getService函數(shù)里面?zhèn)鬟M(jìn)來的參數(shù)reply,它是一個(gè)Parcel對(duì)象。
回到ServiceManagerProxy.getService函數(shù)中,從下面語句返回:
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
接著,就通過下面語句將這個(gè)HelloService的引用讀出來:
IBinder binder = reply.readStrongBinder();
我們看看Parcel.readStrongBinder的實(shí)現(xiàn):
public final class Parcel {
......
/**
* Read an object from the parcel at the current dataPosition().
*/
public final native IBinder readStrongBinder();
......
}
它也是一個(gè)JNI方法,實(shí)現(xiàn)在frameworks/base/core/jni/android_util_Binder.cpp文件中:
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jobject clazz)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
這里首先把Java語言實(shí)現(xiàn)的Parcel對(duì)象class轉(zhuǎn)換成C++語言實(shí)現(xiàn)的Parcel對(duì)象parcel,接著,通過parcel->readStrongBinder函數(shù)來獲得一個(gè)Binder引用。
我們?cè)谇懊鎸W(xué)習(xí)Binder機(jī)制時(shí),在Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過程源代碼分析這篇文章中,曾經(jīng)分析過這個(gè)函數(shù),它最終返回來的是一個(gè)BpBinder對(duì)象,因此,下面的語句:
return javaObjectForIBinder(env, parcel->readStrongBinder());
就相當(dāng)于是:
return javaObjectForIBinder(env, new BpBinder(handle));
這里的handle就是HelloService這個(gè)Binder實(shí)體在Client進(jìn)程中的句柄了,它是由Binder驅(qū)動(dòng)程序設(shè)置的,上層不用關(guān)心它的值具體是多少。至于javaObjectForIBinder這個(gè)函數(shù),我們前面介紹如何獲取Service Manager的Java遠(yuǎn)程接口時(shí)已經(jīng)有詳細(xì)介紹,這里就不累述了,它的作用就是創(chuàng)建一個(gè)BinderProxy對(duì)象,并且把剛才獲得的BpBinder對(duì)象的地址保存在這個(gè)BinderProxy對(duì)象的mObject成員變量中。
最后返回到Hello.onCreate函數(shù)中,從下面語句返回:
helloService = IHelloService.Stub.asInterface( ServiceManager.getService("hello"));
就相當(dāng)于是:
helloService = IHelloService.Stub.asInterface(new BinderProxy()));
回憶一下前面介紹IHelloService接口的定義時(shí),IHelloService.Stub.asInterface是這樣定義的:
public interface IHelloService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService
{
......
public static android.os.IHelloService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IHelloService))) {
return ((android.os.IHelloService)iin);
}
return new android.os.IHelloService.Stub.Proxy(obj);
}
......
}
}
這里的obj是一個(gè)BinderProxy對(duì)象,它的queryLocalInterface返回null,于是調(diào)用下面語句獲得HelloService的遠(yuǎn)程接口:
return new android.os.IHelloService.Stub.Proxy(obj);
相當(dāng)于是:
return new android.os.IHelloService.Stub.Proxy(new BinderProxy());
這樣,我們就獲得了HelloService的遠(yuǎn)程接口了,它實(shí)質(zhì)上是一個(gè)實(shí)現(xiàn)了IHelloService接口的IHelloService.Stub.Proxy對(duì)象。
五. Client通過HelloService的Java遠(yuǎn)程接口來使用HelloService提供的服務(wù)的過程
上面介紹的Hello這個(gè)Activity獲得了HelloService的遠(yuǎn)程接口后,就可以使用它的服務(wù)了。
我們以使用IHelloService.getVal函數(shù)為例詳細(xì)說明。在Hello::onClick函數(shù)中調(diào)用了IHelloService.getVal函數(shù):
public class Hello extends Activity implements OnClickListener {
......
@Override
public void onClick(View v) {
if(v.equals(readButton)) {
int val = helloService.getVal();
......
}
else if(v.equals(writeButton)) {
......
}
else if(v.equals(clearButton)) {
......
}
}
......
}
通知前面的分析,我們知道,這里的helloService接口實(shí)際上是一個(gè)IHelloService.Stub.Proxy對(duì)象,因此,我們進(jìn)入到IHelloService.Stub.Proxy類的getVal函數(shù)中:
public interface IHelloService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService
{
......
private static class Proxy implements android.os.IHelloService
{
private android.os.IBinder mRemote;
......
public int getVal() 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);
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
......
static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
......
}
這里我們可以看出,實(shí)際上是通過mRemote.transact來請(qǐng)求HelloService執(zhí)行TRANSACTION_getVal操作。這里的mRemote是一個(gè)BinderProxy對(duì)象,這是我們?cè)谇懊娅@取HelloService的Java遠(yuǎn)程接口的過程中創(chuàng)建的。
BinderProxy.transact函數(shù)是一個(gè)JNI方法,我們?cè)谇懊嬉呀?jīng)介紹過了,這里不再累述。最過調(diào)用到Binder驅(qū)動(dòng)程序,Binder驅(qū)動(dòng)程序喚醒HelloService這個(gè)Server。前面我們?cè)诮榻BHelloService的啟動(dòng)過程時(shí),曾經(jīng)提到,HelloService這個(gè)Server線程被喚醒之后,就會(huì)調(diào)用JavaBBinder類的onTransact函數(shù):
class JavaBBinder : public BBinder
{
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
......
}
......
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
......
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
......
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
......
JavaVM* const mVM;
jobject const mObject;
};
前面我們?cè)诮榻BHelloService的啟動(dòng)過程時(shí),曾經(jīng)介紹過,JavaBBinder類里面的成員變量mObject就是HelloService類的一個(gè)實(shí)例對(duì)象了。因此,這里通過語句:
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
就調(diào)用了HelloService.execTransact函數(shù),而HelloService.execTransact函數(shù)繼承了Binder類的execTransact函數(shù):
public class Binder implements IBinder {
......
// Entry point from android_util_Binder.cpp's onTransact
private boolean execTransact(int code, int dataObj, int replyObj, int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
try {
res = onTransact(code, data, reply, flags);
} catch (RemoteException e) {
reply.writeException(e);
res = true;
} catch (RuntimeException e) {
reply.writeException(e);
res = true;
} catch (OutOfMemoryError e) {
RuntimeException re = new RuntimeException("Out of memory", e);
reply.writeException(re);
res = true;
}
reply.recycle();
data.recycle();
return res;
}
}
這里又調(diào)用了onTransact函數(shù)來作進(jìn)一步處理。由于HelloService類繼承了IHelloService.Stub類,而IHelloService.Stub類實(shí)現(xiàn)了onTransact函數(shù),HelloService類沒有實(shí)現(xiàn),因此,最終調(diào)用了IHelloService.Stub.onTransact函數(shù):
public interface IHelloService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService
{
......
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
......
case TRANSACTION_getVal:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.getVal();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
......
}
}
函數(shù)最終又調(diào)用了HelloService.getVal函數(shù):
public class HelloService extends IHelloService.Stub {
......
public int getVal() {
return getVal_native();
}
......
private static native int getVal_native();
}
最終,經(jīng)過層層返回,就回到IHelloService.Stub.Proxy.getVal函數(shù)中來了,從下面語句返回:
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
并將結(jié)果讀出來:
_result = _reply.readInt();
最后將這個(gè)結(jié)果返回到Hello.onClick函數(shù)中。
這樣,Client通過HelloService的Java遠(yuǎn)程接口來使用HelloService提供的服務(wù)的過程就介紹完了。
至此,Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析也完成了,整個(gè)Binder機(jī)制的學(xué)習(xí)就結(jié)束了。
重新學(xué)習(xí)Android系統(tǒng)進(jìn)程間通信Binder機(jī)制,請(qǐng)回到Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文。
以上就是Android 系統(tǒng)進(jìn)程通信Binder 機(jī)制Java接口的源碼分析,謝謝大家對(duì)本站的支持,后續(xù)繼續(xù)補(bǔ)充相關(guān)知識(shí)!
- Android 圖文詳解Binder進(jìn)程通信底層原理
- Android通過繼承Binder類實(shí)現(xiàn)多進(jìn)程通信
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過程源代碼分析
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過程源代碼分析
- Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server和Client獲得Service Manager接口之路
- Android Binder 通信原理圖文詳解
相關(guān)文章
android在連拍菜單中增加連拍張數(shù)選項(xiàng)功能實(shí)現(xiàn)代碼
想要增加連拍張數(shù)選項(xiàng)需要在entries, entryvalues中添加兩項(xiàng),同時(shí)在mtk_strings.xml中添加相應(yīng)的字符串,具體如下,感興趣的朋友可以參考下哈2013-06-06
Android NDK開發(fā)之:配置環(huán)境的詳解
本篇文章是對(duì)Android中的配置環(huán)境進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android使用MediaRecorder類進(jìn)行錄制視頻
這篇文章主要介紹了Android使用MediaRecorder類進(jìn)行錄制視頻的相關(guān)資料,需要的朋友可以參考下2015-10-10
Android編程實(shí)現(xiàn)使用webView打開本地html文件的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)使用webView打開本地html文件的方法,結(jié)合實(shí)例形式分析了Android中webview布局及打開HTML文件的功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-02-02
新版Android studio導(dǎo)入微信支付和支付寶官方Demo問題解決大全
這篇文章主要為大家詳細(xì)介紹了新版Android studio導(dǎo)入微信支付和支付寶官方Demo問題的解決大全,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
android手機(jī)端與PC端使用adb forword通信
這篇文章主要介紹了android手機(jī)端與PC端使用adb forword通信的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android中數(shù)據(jù)庫常見操作實(shí)例分析
這篇文章主要介紹了Android中數(shù)據(jù)庫常見操作,以完整實(shí)例形式較為詳細(xì)的分析了Android基于數(shù)據(jù)庫類進(jìn)行數(shù)據(jù)庫的增刪改查等操作技巧,需要的朋友可以參考下2015-10-10

