<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Binder in Java

      Android在Native層實現了進程間的Binder通信,但是上層應用程序的開發及Framework的實現都是Java,用Java層再實現一次肯定是不合理的,Java可以通過JNI調用Native Code,所以通過JNI復用Binder在Native層的實現就是一個順理成章的事情。

      注冊Service

      在Init進程的init2階段,系統啟動了ServerThread,在ServerThread中會啟動很多用Java實現的系統服務,比如說PowerService:

      power = new PowerManagerService();
      ServiceManager.addService(Context.POWER_SERVICE, power);

      新建Server端實體,然后向ServiceManager注冊,從代碼表面看是和Native層Binder一樣的。PowerManagerService繼承自Java層的Binder類:

      public final class PowerManagerService extends IPowerManager.Stub
      public interface IPowerManager extends android.os.IInterface {
          public static abstract class Stub extends android.os.Binder implements android.os.IPowerManager {

      所以在new PowerManagerService時會調用Binder的構造函數,Binder的構造函數中調用了init(),init是native方法,執行JNI的android_os_Binder_init:

      static void android_os_Binder_init(JNIEnv* env, jobject obj)
      {
          JavaBBinderHolder* jbh = new JavaBBinderHolder();
          if (jbh == NULL) {
              jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
              return;
          }
          ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
          jbh->incStrong((void*)android_os_Binder_init);
          env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
      }

      在android_os_Binder_init,新建了一個JavaBBinderHolder對角,并將其指針保存在了obj即Binder的gBinderOffsets.mObject域中,而gBinderOffsets.mObject又是個什么東西?看一下它的定義:

      static struct bindernative_offsets_t
      {
          jclass mClass;
          jmethodID mExecTransact;
          jfieldID mObject;
      } gBinderOffsets;

      在AndroidRuntine::startReg中會調用register_android_os_Binder,register_android_os_Binder會調用int_register_android_os_Binder等函數建立Java層Binder、BinderProxy、BinderInternal、Log等與Native層的映射關系。比如在int_register_android_os_Binder中會通過JNI標準的方法GetMethodID等初始化gBinderOffsets:

      static int int_register_android_os_Binder(JNIEnv* env)
      {
          jclass clazz;
      
          clazz = env->FindClass(kBinderPathName);
          LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder");
      
          gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
          gBinderOffsets.mExecTransact
              = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
          assert(gBinderOffsets.mExecTransact);
      
          gBinderOffsets.mObject
              = env->GetFieldID(clazz, "mObject", "I");
          assert(gBinderOffsets.mObject);
      
          return AndroidRuntime::registerNativeMethods(
              env, kBinderPathName,
              gBinderMethods, NELEM(gBinderMethods));
      }

      在android_os_Binder_init中new了一個JavaBBinderHolder,JavaBBinderHolder new了一個JavaBBinder保存到了自己的成員wp<JavaBBinder> mBinder中。

      JavaBBinder繼承自Native層的BBinder,并且將Java層的Binder對象(此處即PowerManagerService)保存到了成員mObject中,并通過object()方法返回。

      現在我們發現,JavaBinder,BinderBBinderHolder,JavaBBinder存在相互引用關系:

      • PowerManagerService.mObject->JavaBBinderHolder
      • JavaBBinderHolder.mBinder->JavaBBinder
      • JavaBBinder.mObject->PowerManagerService

      Binder是一種Client-Server類型的IPC,PowerManagerService屬于Server端,從Native Binder中我們知道,Client通過BpBinder經由Binder Driver、BBinder與Serverr通信,PowerManagerService通過JavaBBinderHolder引用JavaBBinder,而JavaBBinder繼承自BBinder,符合了Server的條件,Server實體有了,接下來就要向ServiceManager注冊,通過以下方法:

      ServiceManager.addService(Context.POWER_SERVICE,power);
      // In ServiceManager public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }

       BinderInternal.getContextObject是一個Native方法,調用JNIandroid_os_BinderInternal_getContextObject:

      static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
      {
          sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
          return javaObjectForIBinder(env, b);
      }

      ProcessState::self()->getContextObject就很熟悉了,在Binder in Native中可以知道,這個調用返回new BpBinder(0)。

      javaObjectForIBinder的作用就是,新建一個Java層的BinderProxy對象,將Native層的BpBinder保存到BinderProxy.mObject,并將BinderProxy的弱引用通過attachObject保存到Native層的BpBinder(成員mObjects中),這樣Java層的BinderProxy與Native層的BpBinder就可以相互引用了。Java層的BinderProxy及其在Native層的表示間的映射關系同Binder類一樣也是在register_android_os_Binder中建立的。

      上面紅色的部分就等效于:

      gServiceManager = ServiceManagerNative.asInterface(new BinderProxy());

       ServiceManagerNative繼承自IServiceManager與Java層的Binder類,BinderProxy可以引用BpBinder。asInterface就像Native Binder中的interface_cast的,asInterface實現可以簡化為:

      return new ServiceManagerProxy(obj);

      obj是BinderProxy對象。ServiceManagerProxy直接將這個BinderProxy對象保存在了成員mRemote中,并通過asBinder返回。

      ServiceManagerProxy同時實現了IServiceManager,而且由其名字可知,ServiceManagerProxy是作為ServiceManager在Client端的代理的,看下它的addService的實現:

      public void addService(String name, IBinder service, boolean allowIsolated)
                  throws RemoteException {
              Parcel data = Parcel.obtain();
              Parcel reply = Parcel.obtain();
              data.writeInterfaceToken(IServiceManager.descriptor);
              data.writeString(name);
              data.writeStrongBinder(service);
              data.writeInt(allowIsolated ? 1 : 0);
              mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
              reply.recycle();
              data.recycle();
          }

      writeStrongBinder是Native方法,調用android_os_Parcel_writeStrongBinder,在android_os_Parcel_writeStrongBinder將Java Parcel轉換成Native Parcel(Native Parcel的指針保存在Java Parcel的成員變量中),然后調用以下語句:

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

      sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)根據obj返回JavaBBinder或Native BpBinder,在這里傳入的obj 是PowerManagerService,返回JavaBBinder。接下來調用了mRemote.transact,mRemote是BinderProxy的對象。

      BinderProxy的transact是Native方法,調用JNIandroid_os_BinderProxy_transact,在android_os_BinderProxy_transact中通過:

      IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject);
      ...
      status_t err = target->transact(code, *data, reply, flags);

      獲取到BinderProxy中保存的BpBinder,然后調用BpBinder的transact,到這里就和Native Binder的調用流程一樣了,Native ServiceManager會注冊我們的Service,在這里是PowerManagerService。

       獲得注冊的Service

      Service已經向ServiceManager注冊了,那么我們怎么獲得所注冊的Service,或者更準確地說,怎么獲得所注冊的Service的代理呢?

      回想下我們在APK中是怎么獲取系統服務的:

      PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

      看一下getSystemService的實現,位于ContextImpl中:

          @Override
          public Object getSystemService(String name) {
              ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
              return fetcher == null ? null : fetcher.getService(this);
          }
      
              registerService(POWER_SERVICE, new ServiceFetcher() {
                      public Object createService(ContextImpl ctx) {
                          IBinder b = ServiceManager.getService(POWER_SERVICE);
                          IPowerManager service = IPowerManager.Stub.asInterface(b);
                          return new PowerManager(ctx.getOuterContext(),
                                  service, ctx.mMainThread.getHandler());
                      }});

      1. ServiceManager.getService獲得IBinder對象

      同ServiceManager.addService一樣,ServiceManager.getService首先獲得一個ServiceManagerProxy的對象,然后調用它的getService方法:

          public IBinder getService(String name) throws RemoteException {
              ...
              mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
              IBinder binder = reply.readStrongBinder();
              ...
              return binder;
          }

      mRemote是BinderProxy對象,內部引用了BpBinder,調用BinderProxy的Native方法transact與Binder通信,然后通過readStrongBinder()讀取返回的數據,一個IBinder對象。

      readStrongBinder中通過javaObjectForIBinder返回了BinderProxy對象,前面已經說過。

      2. 通過asInterface將獲得的IBinder對象轉換成IPowerManager對象

      IPowerManager.Stub.asInterface可以簡化為:

      return new android.os.IPowerManager.Stub.Proxy(obj);

      Proxy只是將傳入的參數(BinderProxy)保存到了成員mRemote中并通過asBinder返回。

      Proxy與Stub都是IPowerManager.aidl編譯后生成的類,都位于IPowerManager.java中。關于aidl網上有很多資料。

      3. IPowerManager對象是不向外暴露的,構造一個PowerManager封裝IPowerManager返回。

      PowerManager只是將IPowerManager保存在了成員變量中,PowerManager中保存了BinderProxy,BinderProxy中引用了Native BpBinder,就可以與Server進行通信了。

      Server端響應Client請求

      Server端接收到Client的請求后會調用BBinder的transact處理請求,transact會調用虛函數onTransact,JavaBBinder繼承自BBinder,所以會調用JavaBBinder::onTransact,在JavaBBinder::onTransact中有以下一句:

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

      通過JNI反向調用了Java類的方法。前面我們知道了,Java實現的Service中,Service對象,JavaBBinderHolder,JavaBBinder存在相互引用關系,JavaBBinder的成員mObject引用了Java中的Service對象,比如此處的PowerManagerService,而且在int_register_android_os_Binder中通過

      gBinderOffsets.mExecTransact  = env->GetMethodID(clazz, "execTransact", "(IIII)Z");

      將Service的execTransact方法(其實是Binder的方法)保存在了gBinderOffsets.mExecTransact中,所在以JavaBBinder::onTransact中會調用Binder.execTransact。在Binder.execTransact中調用了onTransact,執行子類即Stub類的onTransact方法,在onTransact中根據code值執行相應的方法,最終是調用Service類(繼承自Stub)中相應的方法。

      總結

      Java層通過JNI利用了Native層的Binder,在JNI函數注冊時會建立Java層Binder,BinderProxy,BinderInternal等類與Native層的映射關系。Java層Service實體繼承自Java層的Binder類,在Binder類初始化時會創建一個JavaBBinderHolder作為JavaBBinder的容器,JavaBBinder繼承自BBinder,Java層Binder類引用JavaBBinderHolder,JavaBBinderHolder引用JavaBBinder,JavaBBinder繼承自BBinder并引用Java層的Binder類,這三者互相引用,這樣Java層的Service實體就可以通過BBinder與驅動進行通信了。

      進程向Java層的ServiceManager代理發送GET_SERVICE請求,然后通過JNI向Native層的ServiceManager請求服務,Native層的ServiceManager返回請求的服務的代理對象BpBinder,通過javaObjectForIBinder函數將Native的BpBinder轉化為Java層對應的BinderProxy,然后通過aidl生成的Stub類asInterface方法將BinderProxy封閉到請求的服務的代理對象中,這個代理對象引用了BinderProxy,BinderProxy內部保存了Native層的BpBinder,這樣就可以與驅動進行通信了。

      當Server端接收到Client的請求時會通過BBinder的transact調用Server的服務,BBinder的transact調用虛函數onTransact,這樣就會調到BBinder的子類JavaBBinder的onTransact,而JavaBinder::onTransact會通過JNI反向調用到Java層Binder類的execTransact,Binder.execTransact調用onTransact即子類Stub的onTransact,然后根據code值調用Service實體類(繼承自Stub)相應的方法。

      posted @ 2013-09-23 14:52  AngelDevil  閱讀(6757)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品国产乱码久久久久夜深人妻| 韩国美女福利视频在线观看| 亚洲日韩欧美丝袜另类自拍| 桦甸市| 日本内射精品一区二区视频| 精品国产亚洲一区二区三区| 日韩中文字幕免费在线观看| 在线中文字幕国产一区| 美女黄网站人色视频免费国产| 久久精品国产福利一区二区| 亚洲人成在线播放网站| 日韩一区二区在线看精品| 92精品国产自产在线观看481页| 男人扒开女人内裤强吻桶进去| 天堂av资源在线免费| 99精品国产一区在线看| 亚洲日韩av无码中文字幕美国| 欧美丰满熟妇性xxxx| 国产普通话对白刺激| 亚洲国产另类久久久精品网站| 国产一区二区三区的视频| 99久久久国产精品免费无卡顿| 狠狠色丁香婷婷综合| 99精品久久免费精品久久| 亚洲人妻中文字幕一区| 正镶白旗| 久久国产成人高清精品亚洲| 亚洲一区二区三区在线观看播放| 99福利一区二区视频| 香蕉乱码成人久久天堂爱| 成在线人永久免费视频播放| 青青草国产精品日韩欧美| 亚洲尤码不卡av麻豆| 盐津县| 精品国产女同疯狂摩擦2| 成人免费无遮挡在线播放| 老司机午夜精品视频资源| 熟妇人妻久久精品一区二区| 乱妇乱女熟妇熟女网站| 又大又粗又爽的少妇免费视频| 精品无码久久久久久尤物|