How the RPC layer (Java implementation) of the client side of the Java implementation invokes the IPC layer (C + + implementation) via JNI to send data
TestServer through AddService to Service_manager register when TestServer is client side, Service_manager is server side;
TestClient through GetService to Service_manager request service when TestClient is client side, Service_manager is server side;
TestClient calls the RPC layer SayHello or sayhello_to sends the request to Testserver,testclient is the client side, TestServer is the server side;
(1) AddService
Getiservicemanager (). AddService
GetService
Getiservicemanager (). GetService
Getiservicemanager () returns the Servicemanagerproxy object, and the AddService and GetService functions in the object are called Mremote.transact to send the data after the data is constructed.
(2) SayHello and sayhello_to
Mremote.transact is used to send data after constructing good data, Mremote is in IHelloService.Stub.Proxy class
(3) Unified use Mremote.transact to send data, mremote for the purpose, the source is the caller of the function, the data is stored in the parameters of the Transact function;
For Addservice/getservice, its mremote is a Java Binderproxy object, its mobject points to a C + + Bpbinder object, this bpbinder mhandle=0;
corresponding to Sayhello/sayhello_to, whose mremote is a Java Binderproxy object, its mobject points to a C + + Bpbinder object, this Bpbinder mhandle= 1; This comes as GetService ("Hello")
Construction of Mremote in 5.1 servicemanagerproxy (for Addservice/getservice)
Guess: Using 0 to construct a Java Binderproxy object directly
Getiservicemanager (). AddService/Getiservicemanager (). GetService
Getiservicemanager ()
Return Servicemanagernative.asinterface (Binderinternal.getcontextobject ())
A. Binderinternal.getcontextobject ()//Gets a Java Binderproxy object where mobject points to the new Bpbinder (0);
Getcontextobject It is a JNI call, corresponding to Android_os_binderinternal_getcontextobject,//Android_util_binder.cpp
Android_os_binderinternal_getcontextobject
Sp<ibinder> B = processstate::self ()->getcontextobject (NULL);
Return Getstrongproxyforhandle (0);
b = new Bpbinder (handle); Mhandle = 0
Return Javaobjectforibinder (env, b);//b = new Bpbinder (0), Mhandle = 0
Use C code to call NewObject to create a Java Binderproxy object
Javaobjectforibinder (env, B)
Object = Env->newobject (Gbinderproxyoffsets.mclass, gbinderproxyoffsets.mconstructor);
Set the object's Mobject = Val.get = b = new Bpbinder (0)
Env->setlongfield (object, Gbinderproxyoffsets.mobject, (Jlong) val.get ());
return object;
B. servicemanagernative.asinterface
New Servicemanagerproxy (obj); obj = Binderproxy Object
Mremote = obj = Binderproxy object, where Mobject points to new Bpbinder (0);
How the Mremote in the 5.2 Hello service is constructed
A. IBinder binder = Servicemanager.getservice ("Hello");
Guess: Its return value is a Java Binderproxy object, where the Mobject=new bpbinder (handle)
New Servicemanagerproxy (). GetService ("Hello")
....
IBinder binder = Reply.readstrongbinder ();
Nativereadstrongbinder//Parcel.java
Nativereadstrongbinder is a JNI call, and the corresponding code is Android_os_parcel_readstrongbinder
Android_os_parcel_readstrongbinder
Convert a Java Parce object to a C + + parcel Object
The client program sends a GETSERVICE request to Sevice_manager,
Get a reply to reply, which contains Flat_binder_object
It is encapsulated as a C + + parcel Object
parcel* Parcel = reinterpret_cast<parcel*> (nativeptr);
/* Parcel->readstrongbinder () should be a new bpbinder (handle)
* Unflatten_binder (Processstate::self (), *this, &val);
* *out = Proc->getstrongproxyforhandle (Flat->handle);
* b = new Bpbinder (handle);
*/
It creates a Java Binderproxy object, where the Mobject=new Bpbinder (handle) object
Return Javaobjectforibinder (env, Parcel->readstrongbinder ());
B. Ihelloservice svr = IHelloService.Stub.asInterface (binder);
New IHelloService.Stub.Proxy (obj); obj = Binder obtained by step a
Mremote = remote;
5.3 Now know: Mremote is a Java Binderproxy object
Take a look at Mremote.transact ()
Transactnative (Code, data, reply, flags);
It is a jni call that corresponds to the android_os_binderproxy_transact
Android_os_binderproxy_transact
Remove the mobject from the Java Binderproxy object, which is a Bpbinder object
ibinder* target = (ibinder*) env->getlongfield (obj, gbinderproxyoffsets.mobject);
Then call Bpbinder's Transact
status_t err = target->transact (code, *data, reply, flags);
9.12 Binder System _java Implementation _ internal mechanism _client end