Binder源碼分析之Java層__Java

來源:互聯網
上載者:User
  前面的幾節中我們介紹了Native層Binder通訊的原理和用法,那麼在Java層如何使用Binder通訊呢。其原理又與Native層的Binder有什麼關係呢。
        與Native層的ServiceManager類似,Android在Java層也有一個ServiceManager用於處理Java層Service的註冊、申請。只不過, Java層的這個ServiceManager,其實是在Java層建立的ServiceManager的代理,他把Java層用戶端的各項請求傳遞到Native層的ServiceManager進行處理
        而對於其他Java層的Service來說,用戶端得到的Service遠程代理對象,就是Native層得到的BpXXXService對象。
        接下來我們分四部分來介紹Java層Binder機制:
        1、ServiceManager的結構
        2、如何註冊一個Service
        3、如何得到一個Service

        4、Service代理對象方法的過程


一、ServiceManager的結構         我們來看一下ServiceManager類的代碼: [java] view plain copy @ServiceManager.java(google-code\frameworks\base\core\java\android\os\ServiceManager.java)   public final class ServiceManager {       private static IServiceManager getIServiceManager() {       }       public static IBinder getService(String name) {       }       public static void addService(String name, IBinder service) {       }       public static void addService(String name, IBinder service, boolean allowIsolated) {       }       public static IBinder checkService(String name) {       }       public static String[] listServices() throws RemoteException {       }       public static void initServiceCache(Map<String, IBinder> cache) {       }   }  

        這個類比較簡單,而且我們看到,ServiceManager沒有繼承任何的類,那麼他是如何?“管理員”的角色呢。


二、如何在Java層通過ServiceManager註冊一個Service         Android啟動時,將會在SystemServer中的ServerThread線程中將一些重要的Java層Service註冊並啟動,我們在這裡挑選負責狀態列管理的StatusBarManagerService來分析。 [java] view plain copy @SystemServer.java(google-code\frameworks\base\services\java\com\android\server\SystemServer.java)   class ServerThread extends Thread {       @Override       public void run() {           try {               statusBar = new StatusBarManagerService(context, wm);               //調用ServiceManager註冊服務               ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);           } catch (Throwable e) {               reportWtf("starting StatusBarManagerService", e);           }       }   }           我們看到,作為一個Service,可以通過調用ServiceManager的addService()方法註冊自己。註冊的時候傳遞了兩個參數,Context.STATUS_BAR_SERVICE作為該Service的name,StatusBarManagerService作為該Service的BBinder子類對象,一起傳遞給了ServiceManager。這樣的形式正符合Native層ServiceManager中Service的註冊方式。
        我們來看ServiceManager的addService()方法: [java] view plain copy @ServiceManager.java   public static void addService(String name, IBinder service) {       try {           getIServiceManager().addService(name, service, false);       } catch (RemoteException e) {           Log.e(TAG, "error in addService", e);       }   }           在addService()內部,把addService()的請求轉寄給了getIServiceManager()得到的對象。 [java] view plain copy private static IServiceManager sServiceManager;   private static IServiceManager getIServiceManager() {       if (sServiceManager != null) {           //單例模式           return sServiceManager;       }       //得到ServiceManager的Java層代理對象       sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());       return sServiceManager;   }           這裡看到,通過getIServiceManager()可以得到一個IServiceManager類型的sServiceManager對象, 那麼這個對象究竟是什麼屬性的呢
        其實 我們通過getIServiceManager()得到的就是Java層中的ServiceManager的代理對象ServiceManagerProxy。為了得到這個對象,我們需要經過兩步的準備:
        1、通過Native層的調用得到ServiceManager的遠程對象BpBinder
            ----也就是BinderInternal.getContextObject()的操作
        2、把ServiceManager的BpBinder封裝為Java層可用的ServiceManagerProxy對象
            ----也就是ServiceManagerNative().asInterface()的操作
        下面我們來詳細分析這兩個步驟
2.1、得到ServiceManager的BpBinder對象過程         這一步中我們將會看到, 如何通過BinderInternal.getContextObject()得到ServiceManager的BpBinder()對象,下面我們來看這個方法的聲明: [java] view plain copy @BinderInternal.java(google-code\frameworks\base\core\java\com\android\internal\os\BinderInternal.java)   public static final native IBinder getContextObject();           他的聲明方式說明這個方法是在Native中被實現的,那麼他具體定義是在哪裡呢。
        我們簡單來說一下流程。
        在Java虛擬機器啟動時,將會註冊一系列的native方法 [java] view plain copy @AndroidRuntime.cpp(google-code\frameworks\base\core\jni\AndroidRuntime.cpp)   void AndroidRuntime::start(const char* className, const char* options) {       //開始註冊方法       if (startReg(env) < 0) {           return;       }   }           在虛擬機器啟動時,將會通過startReg()方法去註冊jni: [java] view plain copy int AndroidRuntime::startReg(JNIEnv* env) {       //註冊gRegJNI列表中的jni方法       if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {           env->PopLocalFrame(NULL);           return -1;       }       return 0;   }           在上面的startReg()中將會遍曆gRegJNI列表並註冊,我們來看需要註冊的列表內容: [java] view plain copy static const RegJNIRec gRegJNI[] = {       REG_JNI(register_android_os_Binder),   };           其中就包括了register_android_os_Binder(): [java] view plain copy @android_util_Binder.cpp(google-code\frameworks\base\core\jni\android_util_Binder.cpp)   int register_android_os_Binder(JNIEnv* env) {       //註冊BinderInternal中的jni       if (int_register_android_os_BinderInternal(env) < 0)           return -1;       return 0;   }           在register_android_os_Binder中對BinderInternal中的jni進行註冊: [java] view plain copy static int int_register_android_os_BinderInternal(JNIEnv* env) {       jclass clazz;       //根據路徑找到類       clazz = env->FindClass(kBinderInternalPathName);       gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz);       gBinderInternalOffsets.mForceGc = env->GetStaticMethodID(clazz, "forceBinderGc", "()V");          //註冊gBinderInternalMethods中的jni       return AndroidRuntime::registerNativeMethods(               env, kBinderInternalPathName,               gBinderInternalMethods, NELEM(gBinderInternalMethods));   }           我們再來看gBinderInternalMethods中定義的方法: [java] view plain copy 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", (

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.