上一篇 Binder機制,從Java到C (2. IPC in System Service :AMS) 中提到 Application是通過ServiceManager找到了AMS 的service代理對象。那在這個之前當然是要先找到ServiceManager的代理對象,才能調用ServiceManager的服務嘛。下面就看看怎么來獲得這個代理對象的吧:
還記得上一篇調用的ServiceManager的方法吧:IBinder b = ServiceManager.getService("activity");
那下面就來看一下ServiceManager.getService()是怎樣的:
/frameworks/base/core/java/android/os/ServiceManager.java
1 public final class ServiceManager { 2 ... 3 private static IServiceManager getIServiceManager() { 4 if (sServiceManager != null) { 5 return sServiceManager; 6 } 7 8 // Find the service manager 9 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); (1)10 return sServiceManager;11 }12 13 public static IBinder getService(String name) {14 try {15 IBinder service = sCache.get(name);16 if (service != null) {17 return service;18 } else {19 return getIServiceManager().getService(name);20 }21 } catch (RemoteException e) {22 Log.e(TAG, "error in getService", e);23 }24 return null;25 }
說明:
(1) :根據(jù)前兩篇的分析,我們可以推測是在BinderInternal.getContextObject()中,找到了ServiceManager的BinderProxy,似乎和前面有些不同。接著看。
那就接著看BinderInternal.getContextObject()有什麼不同:
/framework/base/core/java/com/android/internal/os/BinderInternal.java
1 public class BinderInternal { 2 …. 3 public static final native IBinder getContextObject(); 4 …. 5 }
會getContextObject()是個JNI方法, ServiceManager難道運行在native環(huán)境?答案是Yes! ServiceManager確實運行在Native環(huán)境。
繼續(xù)看,在/framework/base/core/jni/android_util_Binder.cpp找到了對應的方法:
1 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)2 {3 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);4 return javaObjectForIBinder(env, b); //按照字面意思來看,就是把一個Native層的Binder代理對象轉化成Java層的Binder代理對象5 }
這個方法只有兩句代碼,第一句看著就是找一個IBinder對象啦,然后第二句,就是把一個Native里面的Binder代理對象轉化成Java層的Binder代理對象,然后好返回給Java層。
來看一下第一句代碼,在/frameworks/native/libs/binder/ProcessState.cpp里:
1 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)2 {3 return getStrongProxyForHandle(0);4 }
里面的這一句代碼就暫時先不展開了,不然沒完沒了了,這里按字面意思也可以看出,是根據(jù)一個handle來獲得一個Native層的Binder代理對象。而0是一個default值。代表servicemanager的binder handle值。所以這里你給個0,就返回給你servicemanager的Binder代理對象。
那到這里,我們就認為通過BinderInternal.getContextObject(),獲得了Native的一個binder 代理對象后,javaObjectForIBinder()會創(chuàng)建一個BinderProxy對象返回到Java層去。
經過上面的分析,我們可以知道:ServiceManager的Stub端在Native層。ServiceManager的Proxy端在Java層。
結合前面兩篇總結一下:
1. Application通過AMS的static 方法,先得到ServiceManager的BinderProxy。
2. 然后從ServiceManager獲得AMS的BinderProxy,從而可以使用AMS的遠程服務方法。
3. Application通過AMS的遠程服務方法,如bindservice(), 將Application Remote Service的BinderProxy提供給Activity,從而Activity可以遠程調用這些remote service 的服務。
現(xiàn)在可以串起來了吧。