In the previous sections we introduced the principle and usage of native layer binder communication, so how to use binder communication in the Java layer. Its principle and native layer of binder have what relationship.
Similar to the native layer's ServiceManager, Android also has a servicemanager in the Java layer to process the registration and application of Java Layer service. Just
this servicemanager of the Java layer, in fact, is an agent of the ServiceManager built in the Java layer that passes requests from the Java layer client to the servicemanager of the native layer for processing。
But for other Java layer service, the client obtains the service remote proxy object, is the native layer obtains Bpxxxservice object.
Next we will introduce the Java Layer Binder mechanism in four parts:
1, the structure of ServiceManager;
2. How to register a service;
3. How to get a service;
4, the Service Agent object method process ;
I. Structure of the ServiceManagerLet's take a look at the code for the ServiceManager class:[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) { } }
This class is relatively simple, and we see that ServiceManager does not inherit any of the classes, so how does he implement the role of "admin"?
second, how to register a service through ServiceManager in the Java layerWhen Android starts, some important Java-layer service will be registered and launched in the Serverthread thread in Systemserver, where we'll select the Statusbarmanagerservice for status bar management to analyze.[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,&NBSP;WM); //Call ServiceManager Registration service servicemanager.addservice (Context.STATUS_BAR _service, statusbar); } catch ( Throwable e) { REPORTWTF ("starting  Statusbarmanagerservice ", e); } } } We see, as a service, You can register yourself by calling the ServiceManager AddService () method. Two parameters were passed when registering, Context.status_bar_service as the name,statusbarmanagerservice of the service as the Bbinder subclass object of the service. Passed along to the ServiceManager. Such a form is in line with the native Layer ServiceManager service registration method.
Let's look at ServiceManager's AddService () method:[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); The request for AddService () is forwarded to the Getiservicemanager () object within AddService ().[Java]View plain copy private static Iservicemanager Sservicemanager; private static Iservicemanager Getiservicemanager () {if (Sservicemanager!= null) {//single case mode Retu RN Sservicemanager; ///Get ServiceManager Java Layer proxy Object sservicemanager = Servicemanagernative.asinterface (binderinternal.getcontextobj ECT ()); return sservicemanager; Here, you can get a Iservicemanager type of Sservicemanager object by Getiservicemanager (),So what's the nature of this object?。
In factwhat we get through Getiservicemanager () is the proxy object of the ServiceManager in the Java layer Servicemanagerproxy。 In order to get this object, we need to go through two steps:
1, through the native layer of the call to get ServiceManager remote objects Bpbinder
----is the operation of Binderinternal.getcontextobject ()
2, the ServiceManager Bpbinder encapsulated as the Java layer available Servicemanagerproxy objects
----is the operation of Servicemanagernative (). Asinterface ()
Let's take a detailed analysis of these two steps
2.1, get the ServiceManager Bpbinder object processIn this step we will see thathow to get the Bpbinder () object of ServiceManager through Binderinternal.getcontextobject (), let's look at the declaration of this method:[Java]View plain copy @BinderInternal. Java (google-code\frameworks\base\core\java\com\android\internal\os\ Binderinternal.java) public static final native IBinder Getcontextobject (); His declarative way of saying that this method is implemented in native, what is his specific definition?
Let's briefly describe the process.
A series of native methods will be registered when the Java Virtual machine is started[Java]View plain copy @AndroidRuntime. cpp (google-code\frameworks\base\core\jni\androidruntime.cpp) void Androidruntime:: Start (const char* className, const char* options) {//Start registration method if (Startreg (env) < 0) {return; When the virtual machine is started, the JNI will be registered through the Startreg () method:[Java]View plain copy int Androidruntime::startreg (jnienv* env) {///register JNI method in Gregjni list if Register_jni_procs (GREGJN I, Nelem (GREGJNI), env) < 0) {env->poplocalframe (NULL); return-1; return 0; In the Startreg () above, you will traverse the Gregjni list and register, and we'll look at the list of things to register:[Java]View plain copy static const REGJNIREC gregjni[] = {Reg_jni (register_android_os_binder),}; This includes the 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) {//JNI if (int_register_android_os_binderinternal (env) < in registered binderinternal 0) Return-1; return 0; Register for JNI in Binderinternal in Register_android_os_binder:[Java] View Plain copy static int int_register_android_os_binderinternal (jnienv* env) { jclass clazz; //class based on path found clazz = env->findclass (kbinderinternalpathname); gBinderInternalOffsets.mClass = (Jclass) env->newglobalref (clazz); gbinderinternaloffsets.mforcegc = env->getstaticmethodid (clazz, " FORCEBINDERGC ", " () V); //jni in registered Gbinderinternalmethods return androidruntime::registernativemethods ( env, kBinderInternalPathName, gbinderinternalmethods, nelem ( Gbinderinternalmethods)); } Let's look at the methods defined in Gbinderinternalmethods: [Java]View plain copy static const Jninativemethod gbinderinternalmethods[] = {{"Getcontextobject", "() Landroid/os/ibind er; ", (void*) Android_os_binderinternal_getcontextobject}, {" Jointhreadpool "," () V ", (void*) Android_os_binderintern Al_jointhreadpool}, {"Disablebackgroundscheduling", "(Z) V", (void*) Android_os_binderinternal_disablebackgroundsch Eduling}, {"HANDLEGC", "() V", (