欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼分析

 更新時(shí)間:2016年08月29日 17:23:52   作者:羅升陽(yáng)  
本文主要介紹 Android系統(tǒng)進(jìn)程間通信Binder機(jī)制Java 接口源碼分析,這里詳細(xì)介紹了如何實(shí)現(xiàn)Binder 機(jī)制和Java接口直接的通信,有興趣的小伙伴可以參考下

        在前面幾篇文章中,我們?cè)敿?xì)介紹了Android系統(tǒng)進(jìn)程間通信機(jī)制Binder的原理,并且深入分析了系統(tǒng)提供的Binder運(yùn)行庫(kù)和驅(qū)動(dòng)程序的源代碼。細(xì)心的讀者會(huì)發(fā)現(xiàn),這幾篇文章分析的Binder接口都是基于C/C++語(yǔ)言來(lái)實(shí)現(xiàn)的,但是我們?cè)诰帉?xiě)應(yīng)用程序都是基于Java語(yǔ)言的,那么,我們?nèi)绾问褂肑ava語(yǔ)言來(lái)使用系統(tǒng)的Binder機(jī)制來(lái)進(jìn)行進(jìn)程間通信呢?這就是本文要介紹的Android系統(tǒng)應(yīng)用程序框架層的用Java語(yǔ)言來(lái)實(shí)現(xiàn)的Binder接口了。

       熟悉Android系統(tǒng)的讀者,應(yīng)該能想到應(yīng)用程序框架中的基于Java語(yǔ)言的Binder接口是通過(guò)JNI來(lái)調(diào)用基于C/C++語(yǔ)言的Binder運(yùn)行庫(kù)來(lái)為Java應(yīng)用程序提供進(jìn)程間通信服務(wù)的了。JNI在Android系統(tǒng)中用得相當(dāng)普遍,SDK中的Java接口API很多只是簡(jiǎn)單地通過(guò)JNI來(lái)調(diào)用底層的C/C++運(yùn)行庫(kù)從而為應(yīng)用程序服務(wù)的。

       這里,我們?nèi)匀皇峭ㄟ^(guò)具體的例子來(lái)說(shuō)明Binder機(jī)制在應(yīng)用程序框架層中的Java接口,主要就是Service Manager、Server和Client這三個(gè)角色的實(shí)現(xiàn)了。通常,在應(yīng)用程序中,我們都是把Server實(shí)現(xiàn)為Service的形式,并且通過(guò)IServiceManager.addService接口來(lái)把這個(gè)Service添加到Service Manager,Client也是通過(guò)IServiceManager.getService接口來(lái)獲得Service接口,接著就可以使用這個(gè)Service提供的功能了,這個(gè)與運(yùn)行時(shí)庫(kù)的Binder接口是一致的。

       前面我們學(xué)習(xí)Android硬件抽象層時(shí),曾經(jīng)在應(yīng)用程序框架層中提供了一個(gè)硬件訪問(wèn)服務(wù)HelloService,這個(gè)Service運(yùn)行在一個(gè)獨(dú)立的進(jìn)程中充當(dāng)Server的角色,使用這個(gè)Service的Client運(yùn)行在另一個(gè)進(jìn)程中,它們之間就是通過(guò)Binder機(jī)制來(lái)通信的了。這里,我們就使用HelloService這個(gè)例子來(lái)分析Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口源代碼。所以希望讀者在閱讀下面的內(nèi)容之前,先了解一下前面在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問(wèn)服務(wù)這篇文章。

       這篇文章通過(guò)五個(gè)情景來(lái)學(xué)習(xí)Android系統(tǒng)進(jìn)程間通信Binder機(jī)制在應(yīng)用程序框架層的Java接口:1. 獲取Service Manager的Java遠(yuǎn)程接口的過(guò)程;2. HelloService接口的定義;3. HelloService的啟動(dòng)過(guò)程;4. Client獲取HelloService的Java遠(yuǎn)程接口的過(guò)程;5.  Client通過(guò)HelloService的Java遠(yuǎn)程接口來(lái)使用HelloService提供的服務(wù)的過(guò)程。

       一.  獲取Service Manager的Java遠(yuǎn)程接口

       我們要獲取的Service Manager的Java遠(yuǎn)程接口是一個(gè)ServiceManagerProxy對(duì)象的IServiceManager接口。我們現(xiàn)在就來(lái)看看ServiceManagerProxy類(lèi)是長(zhǎng)什么樣子的:

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

         再來(lái)看一下是通過(guò)什么路徑來(lái)獲取Service Manager的Java遠(yuǎn)程接口ServiceManagerProxy的。這個(gè)主角就是ServiceManager了,我們也先看一下ServiceManager是長(zhǎng)什么樣子的:

        ServiceManager類(lèi)有一個(gè)靜態(tài)成員函數(shù)getIServiceManager,它的作用就是用來(lái)獲取Service Manager的Java遠(yuǎn)程接口了,而這個(gè)函數(shù)又是通過(guò)ServiceManagerNative來(lái)獲取Service Manager的Java遠(yuǎn)程接口的。

        接下來(lái),我們就看一下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ù)來(lái)創(chuàng)建。在調(diào)用ServiceManagerNative.asInterface函數(shù)之前,首先要通過(guò)BinderInternal.getContextObject函數(shù)來(lái)獲得一個(gè)BinderProxy對(duì)象。

        我們來(lái)看一下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,即下面語(yǔ)句:
              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ù)之前,先來(lái)看兩個(gè)變量gBinderOffsets和gBinderProxyOffsets的定義。

        先看gBinderOffsets的定義:

static struct bindernative_offsets_t 
{ 
  // Class state. 
  jclass mClass; 
  jmethodID mExecTransact; 
 
  // Object state. 
  jfieldID mObject; 
 
} gBinderOffsets; 

       簡(jiǎn)單來(lái)說(shuō),gBinderOffsets變量是用來(lái)記錄上面第二個(gè)類(lèi)圖中的Binder類(lèi)的相關(guān)信息的,它是在注冊(cè)Binder類(lèi)的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)); 
} 

       再來(lái)看gBinderProxyOffsets的定義:

static struct binderproxy_offsets_t 
{ 
  // Class state. 
  jclass mClass; 
  jmethodID mConstructor; 
  jmethodID mSendDeathNotice; 
 
  // Object state. 
  jfieldID mObject; 
  jfieldID mSelf; 
 
} gBinderProxyOffsets; 

       簡(jiǎn)單來(lái)說(shuō),gBinderProxyOffsets是用來(lái)變量是用來(lái)記錄上面第一個(gè)圖中的BinderProxy類(lèi)的相關(guān)信息的,它是在注冊(cè)BinderProxy類(lèi)的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; 
} 

        前面說(shuō)過(guò),這里傳進(jìn)來(lái)的參數(shù)是一個(gè)BpBinder的指針,而B(niǎo)pBinder::checkSubclass繼承于父類(lèi)IBinder::checkSubclass,它什么也不做就返回false。

        于是函數(shù)繼續(xù)往下執(zhí)行:

                    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);  

       由于這個(gè)BpBinder對(duì)象是第一創(chuàng)建,它里面什么對(duì)象也沒(méi)有,因此,這里返回的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)起來(lái):

                   env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());  

        就是通過(guò)BinderProxy.mObject成員變量來(lái)關(guān)聯(lián)的了,BinderProxy.mObject成員變量記錄了這個(gè)BpBinder對(duì)象的地址。

        接下去,還要把它放到BpBinder里面去,下次就要使用時(shí),就可以在上一步調(diào)用BpBinder::findObj把它找回來(lái)了:

               val->attachObject(&gBinderProxyOffsets, refObject, 
                jnienv_to_javavm(env), proxy_cleanup);  

        最后,就把這個(gè)BinderProxy返回到android_os_BinderInternal_getContextObject函數(shù),最終返回到最開(kāi)始的ServiceManager.getIServiceManager函數(shù)中來(lái)了,于是,我們就獲得一個(gè)BinderProxy對(duì)象了。

        回到ServiceManager.getIServiceManager中,從下面語(yǔ)句返回:

                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中,從下面語(yǔ)句返回:

                  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ì)象與之通過(guò)gBinderProxyOffsets關(guān)聯(lián)起來(lái)。

      這樣獲取Service Manager的Java遠(yuǎn)程接口的過(guò)程就完成了。

      二. HelloService接口的定義

      前面我們?cè)趯W(xué)習(xí)Android系統(tǒng)的硬件抽象層(HAL)時(shí),在在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問(wèn)服務(wù)這篇文章中,我們編寫(xiě)了一個(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ù),分別用來(lái)讀寫(xiě)硬件寄存器。

       注意,這是一個(gè)aidl文件,編譯后會(huì)生成一個(gè)IHelloService.java。我們來(lái)看一下這個(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è)文件編譯后的真面目,原來(lái)就是根據(jù)IHelloService接口的定義生成相應(yīng)的Stub和Proxy類(lèi),這個(gè)就是我們熟悉的Binder機(jī)制的內(nèi)容了,即實(shí)現(xiàn)這個(gè)HelloService的Server必須繼續(xù)于這里的IHelloService.Stub類(lèi),而這個(gè)HelloService的遠(yuǎn)程接口就是這里的IHelloService.Stub.Proxy對(duì)象獲得的IHelloService接口。接下來(lái)的內(nèi)容,我們就可以看到IHelloService.Stub和IHelloService.Stub.Proxy是怎么創(chuàng)建或者使用的。

        三. HelloService的啟動(dòng)過(guò)程

        在討論HelloService的啟動(dòng)過(guò)程之前,我們先來(lái)看一下實(shí)現(xiàn)HelloService接口的Server是怎么定義的。

        回憶在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問(wèn)服務(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類(lèi),它通過(guò)本地方法調(diào)用實(shí)現(xiàn)了getVal和setVal兩個(gè)函數(shù)。我們不關(guān)心這兩個(gè)函數(shù)的具體實(shí)現(xiàn),有興趣的讀者可以參考在Ubuntu上為Android系統(tǒng)的Application Frameworks層增加硬件訪問(wèn)服務(wù)一文。

        有了HelloService這個(gè)Server類(lèi)后,下一步就是考慮怎么樣把它啟動(dòng)起來(lái)了。在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定義了SystemServer類(lèi)。SystemServer對(duì)象是在系統(tǒng)啟動(dòng)的時(shí)候創(chuàng)建的,它被創(chuàng)建的時(shí)候會(huì)啟動(dòng)一個(gè)線程來(lái)創(chuàng)建HelloService,并且把它添加到Service Manager中去。

       我們來(lái)看一下這部份的代碼:

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); 
} 

         通過(guò)調(diào)用ServiceManager.addService把一個(gè)HelloService實(shí)例添加到Service Manager中去。

         我們先來(lái)看一下HelloService的創(chuàng)建過(guò)程:

                      new HelloService();  

         這個(gè)語(yǔ)句會(huì)調(diào)用HelloService類(lèi)的構(gòu)造函數(shù),而HelloService類(lèi)繼承于IHelloService.Stub類(lèi),IHelloService.Stub類(lèi)又繼承了Binder類(lèi),因此,最后會(huì)調(diào)用Binder類(lèi)的構(gòu)造函數(shù):

public class Binder implements IBinder { 
  ...... 
   
  private int mObject; 
   
  ...... 
 
 
  public Binder() { 
    init(); 
    ...... 
  } 
 
 
  private native final void init(); 
 
 
  ...... 
} 

        這里調(diào)用了一個(gè)JNI方法init來(lái)初始化這個(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類(lèi)的mObject成員變量中,后面我們會(huì)用到。

        回到ServerThread.run函數(shù)中,我們?cè)賮?lái)看一下ServiceManager.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)分析過(guò)了,它返回的是一個(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類(lèi)是用Java來(lái)實(shí)現(xiàn)的,它跟我們前面幾篇文章介紹Binder機(jī)制時(shí)提到的用C++實(shí)現(xiàn)的Parcel類(lèi)的作用是一樣的,即用來(lái)在兩個(gè)進(jìn)程之間傳遞數(shù)據(jù)。

       這里我們關(guān)注是如何把參數(shù)service寫(xiě)到data這個(gè)Parcel對(duì)象中去的:

                            data.writeStrongBinder(service);  

      我們來(lái)看看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語(yǔ)言實(shí)現(xiàn)的Parcel對(duì)象,通過(guò)parcelForJavaObject把它轉(zhuǎn)換成C++語(yǔ)言實(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語(yǔ)言實(shí)現(xiàn)的Binder對(duì)象,在調(diào)用C++語(yǔ)言實(shí)現(xiàn)的Parcel::writeStrongBinder把這個(gè)對(duì)象寫(xiě)入到parcel對(duì)象時(shí),首先通過(guò)ibinderForJavaObject函數(shù)把這個(gè)Java語(yǔ)言實(shí)現(xiàn)的Binder對(duì)象轉(zhuǎn)換為C++語(yǔ)言實(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類(lèi)的實(shí)例,因此,這里會(huì)進(jìn)入到第一個(gè)if語(yǔ)句中去。

         在前面創(chuàng)建HelloService對(duì)象,曾經(jīng)在調(diào)用到HelloService的父類(lèi)Binder中,曾經(jīng)在JNI層創(chuàng)建了一個(gè)JavaBBinderHolder對(duì)象,然后把這個(gè)對(duì)象的地址保存在Binder類(lèi)的mObject成員變量中,因此,這里把obj對(duì)象的mObject成員變量強(qiáng)制轉(zhuǎn)為JavaBBinderHolder對(duì)象。

         到了這里,這個(gè)函數(shù)的功課還未完成,還剩下最后關(guān)鍵的一步:

                        return jbh != NULL ? jbh->get(env) : NULL;  

        這里就是jbh->get這個(gè)語(yǔ)句了。

        在JavaBBinderHolder類(lèi)中,有一個(gè)成員變量mBinder,它的類(lèi)型為JavaBBinder,而JavaBBinder類(lèi)繼承于BBinder類(lèi)。在前面學(xué)習(xí)Binder機(jī)制的C++語(yǔ)言實(shí)現(xiàn)時(shí),我們?cè)贏ndroid系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Server啟動(dòng)過(guò)程源代碼分析這篇文章中,曾經(jīng)介紹過(guò),IPCThreadState類(lèi)負(fù)責(zé)與Binder驅(qū)動(dòng)程序進(jìn)行交互,它把從Binder驅(qū)動(dòng)程序讀出來(lái)的請(qǐng)求作簡(jiǎn)單的處理后,最后把這個(gè)請(qǐng)求扔給BBinder的onTransact函數(shù)來(lái)進(jìn)一步處理。

        這里,我們就是要把JavaBBinderHolder里面的JavaBBinder類(lèi)型Binder實(shí)體添加到Service Manager中去,以便使得這個(gè)HelloService有Client來(lái)請(qǐng)求服務(wù)時(shí),由Binder驅(qū)動(dòng)程序來(lái)喚醒這個(gè)Server線程,進(jìn)而調(diào)用這個(gè)JavaBBinder類(lèi)型Binder實(shí)體的onTransact函數(shù)來(lái)進(jìn)一步處理,這個(gè)函數(shù)我們?cè)诤竺鏁?huì)繼續(xù)介紹。

       先來(lái)看一下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è)語(yǔ)句:

                    const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));  

       相當(dāng)于是:

                    const status_t err = parcel->writeStrongBinder((JavaBBinderHodler*)(obj.mObject));  

       因此,這里的效果相當(dāng)于是寫(xiě)入了一個(gè)JavaBBinder類(lèi)型的Binder實(shí)體到parcel中去。這與我們前面介紹的Binder機(jī)制的C++實(shí)現(xiàn)是一致的。

       接著,再回到ServiceManagerProxy.addService這個(gè)函數(shù)中,最后它通過(guò)其成員變量mRemote來(lái)執(zhí)行進(jìn)程間通信操作。前面我們?cè)诮榻B如何獲取Service Manager遠(yuǎn)程接口時(shí)提到,這里的mRemote成員變量實(shí)際上是一個(gè)BinderProxy對(duì)象,因此,我們?cè)賮?lái)看看BinderProxy.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)來(lái)的參數(shù)dataObj和replyObj是一個(gè)Java接口實(shí)現(xiàn)的Parcel類(lèi),由于這里是JNI層,需要把它轉(zhuǎn)換為C++實(shí)現(xiàn)的Parcel類(lèi),它們就是通過(guò)我們前面說(shuō)的parcelForJavaObject函數(shù)進(jìn)行轉(zhuǎn)換的。

        前面我們?cè)诜治鋈绾潍@取Service Manager遠(yuǎn)程接口時(shí),曾經(jīng)說(shuō)到,在JNI層中,創(chuàng)建了一個(gè)BpBinder對(duì)象,它的句柄值為0,它的地址保存在gBinderProxyOffsets.mObject中,因此,這里通過(guò)下面語(yǔ)句得到這個(gè)BpBinder對(duì)象的IBinder接口:

                   IBinder* target = (IBinder*) 
                   env->GetIntField(obj, gBinderProxyOffsets.mObject);  

        有了這個(gè)IBinder接口后,就和我們前面幾篇文章介紹Binder機(jī)制的C/C++實(shí)現(xiàn)一致了。

        最后,通過(guò)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)過(guò)程源代碼分析一文。需要注意的是,這里的data包含了一個(gè)JavaBBinderHolder類(lèi)型的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)過(guò)程就完成了。

       四. Client獲取HelloService的Java遠(yuǎn)程接口的過(guò)程

        前面我們?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)程接口來(lái)獲得HelloService的遠(yuǎn)程接口,進(jìn)而調(diào)用HelloService提供的服務(wù)。

        我們看看它是如何借助Service Manager這個(gè)Java遠(yuǎn)程接口來(lái)獲得HelloService的遠(yuǎn)程接口的。在Hello這個(gè)Activity的onCreate函數(shù),通過(guò)IServiceManager.getService函數(shù)來(lái)獲得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")); 
  } 
 
  ...... 
} 

        我們先來(lái)看ServiceManager.getService的實(shí)現(xiàn)。前面我們說(shuō)過(guò),這里實(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; 
} 

         最終通過(guò)mRemote.transact來(lái)執(zhí)行實(shí)際操作。我們?cè)谇懊嬉呀?jīng)介紹過(guò)了,這里的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)看到了,這里就不再列出來(lái)了。不過(guò),當(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)來(lái)的參數(shù)reply,它是一個(gè)Parcel對(duì)象。

       回到ServiceManagerProxy.getService函數(shù)中,從下面語(yǔ)句返回:

                 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);  

       接著,就通過(guò)下面語(yǔ)句將這個(gè)HelloService的引用讀出來(lái):

                       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語(yǔ)言實(shí)現(xiàn)的Parcel對(duì)象class轉(zhuǎn)換成C++語(yǔ)言實(shí)現(xiàn)的Parcel對(duì)象parcel,接著,通過(guò)parcel->readStrongBinder函數(shù)來(lái)獲得一個(gè)Binder引用。

       我們?cè)谇懊鎸W(xué)習(xí)Binder機(jī)制時(shí),在Android系統(tǒng)進(jìn)程間通信(IPC)機(jī)制Binder中的Client獲得Server遠(yuǎn)程接口過(guò)程源代碼分析這篇文章中,曾經(jīng)分析過(guò)這個(gè)函數(shù),它最終返回來(lái)的是一個(gè)BpBinder對(duì)象,因此,下面的語(yǔ)句:

               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ù)中,從下面語(yǔ)句返回:

                       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)用下面語(yǔ)句獲得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通過(guò)HelloService的Java遠(yuǎn)程接口來(lái)使用HelloService提供的服務(wù)的過(guò)程

        上面介紹的Hello這個(gè)Activity獲得了HelloService的遠(yuǎn)程接口后,就可以使用它的服務(wù)了。

        我們以使用IHelloService.getVal函數(shù)為例詳細(xì)說(shuō)明。在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類(lèi)的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í)際上是通過(guò)mRemote.transact來(lái)請(qǐng)求HelloService執(zhí)行TRANSACTION_getVal操作。這里的mRemote是一個(gè)BinderProxy對(duì)象,這是我們?cè)谇懊娅@取HelloService的Java遠(yuǎn)程接口的過(guò)程中創(chuàng)建的。

        BinderProxy.transact函數(shù)是一個(gè)JNI方法,我們?cè)谇懊嬉呀?jīng)介紹過(guò)了,這里不再累述。最過(guò)調(diào)用到Binder驅(qū)動(dòng)程序,Binder驅(qū)動(dòng)程序喚醒HelloService這個(gè)Server。前面我們?cè)诮榻BHelloService的啟動(dòng)過(guò)程時(shí),曾經(jīng)提到,HelloService這個(gè)Server線程被喚醒之后,就會(huì)調(diào)用JavaBBinder類(lèi)的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)過(guò)程時(shí),曾經(jīng)介紹過(guò),JavaBBinder類(lèi)里面的成員變量mObject就是HelloService類(lèi)的一個(gè)實(shí)例對(duì)象了。因此,這里通過(guò)語(yǔ)句:

             jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, 
            code, (int32_t)&data, (int32_t)reply, flags);  

         就調(diào)用了HelloService.execTransact函數(shù),而HelloService.execTransact函數(shù)繼承了Binder類(lèi)的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ù)來(lái)作進(jìn)一步處理。由于HelloService類(lèi)繼承了IHelloService.Stub類(lèi),而IHelloService.Stub類(lèi)實(shí)現(xiàn)了onTransact函數(shù),HelloService類(lèi)沒(méi)有實(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)過(guò)層層返回,就回到IHelloService.Stub.Proxy.getVal函數(shù)中來(lái)了,從下面語(yǔ)句返回:

                  mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);  

       并將結(jié)果讀出來(lái):

                    _result = _reply.readInt();  

       最后將這個(gè)結(jié)果返回到Hello.onClick函數(shù)中。

       這樣,Client通過(guò)HelloService的Java遠(yuǎn)程接口來(lái)使用HelloService提供的服務(wù)的過(guò)程就介紹完了。

       至此,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í)!

相關(guān)文章

最新評(píng)論