前面的幾節中我們介紹了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", (