In addition, there is also the possibility of process communication in our own programs (especially in some large apps).
QQ: Not logged in.
Wechat: After a period of use:
Scenario: Start the location service in the service, which is a separate process. You need to get the location results in the main process of the App or other apps.
Services provide methods exposed to other processes and provide ServiceId annotation tags. Service implementations must be given the same ServiceId and method implementation. LocationManager does not have to inherit the interface of ILocationManager j, but in order to ensure the method signature, it is recommended to inherit it uniformly. (otherwise, one is getLocation and the other is getLocation2, which is not fun. )
Perform positioning in the service, and the positioning results are recorded in LocationManager. Use the framework to register the LocationManager in this service.
There is no need to return the Binder object, which means that users do not need to write cumbersome AIDL files without any hints.
Within this framework, multiple reserved services of com. enjoy.ipcservice $ ipcservicex will be provided to communicate with other processes. If multiple processes in an App need to provide their own services, they can use different services. So in essence, it still relies on service+binder communication, but the framework hides the details and is easier to use.
After obtaining the result object, you can call a remote method (RPC call) just like a local method.
In use, it simplifies:
1, you don't need to define AIDL interface yourself, and the JavaBean you use doesn't need to implement Parcelable interface;
2. You don't need to use bindService directly to get the Binder object of the client;
The server needs to define an interface (ILocationManager) that exposes services. If the client is another APP, you need to put the interface class in your own source code (no interface implementation is needed). Methods defined in the interface are methods provided by the server to other processes.
The whole framework includes the interface between the server and the client.
During the service process, the ServiceId and the corresponding service implementation class object: service table will be cached, and all the method lists in the service implementation also need to be recorded: method table. Because there may be multiple methods in a service, its data structure is mapped.
When the client needs to call the service, the ServiceId, MethodName and parameters required for executing the method are passed to the server, and the server can execute the method in the service by reflecting the method #invoke lookup table.
The client's request is encapsulated as a request object, and the server's response is encapsulated as a response object.
The server only needs to expose the service interface to other processes, so the server only needs to call the registration interface register of the framework to register the service implementation. (The service implementation is registered, not the service interface)
When registering, you can get the ServiceId on the class by reflection to record the service table. At the same time, all public methods in the class can be obtained by reflection, and the method table can be recorded.
Because the essence of the framework is still to use Binder to complete communication, in order to communicate with other processes, multiple reservation services are provided within the framework.
The communication service will return a Binder class object generated by AIDL.
The client sends a request to the server using the send method.
Implementation of the server after receiving the request:
The client needs to establish a connection with the server first, so the connect method is provided in the framework, and the bindService is encapsulated internally to realize the binding with the Service (IPCService of the server).
The only thing to note is:
When the binding is completed, the client can obtain the IIPCService object provided by the server communication service, and the client calls IIPCService#send to initiate the request.
When we need to locate. You should call the locationmanager. getdefault()。 getlocation()。 This call needs to execute two methods of LocationManager: getDefault and getLocation.
However, this object exists on the server, how can the client get it?
We can use dynamic proxy to create a "fake" service interface object (proxy) on the client.
When we execute the method (getLocation) of this proxy object, we will call back the IPCInvocationHandler#invoke method, in which the framework will send a request to the server: IIPCService#send.
GetLocation will return an object where Location records location information, which will be sent by json serialization on the server, so the client only needs to get the return type of the method here and deserialize it.
RPC refers to calling a function from the client to the server through parameter passing and getting the return result, hiding the communication details at the bottom. Call a remote function like a local function.
For example, we use Okhttp to make a network request:
This method is obviously not RPC.
After modification:
RPC: We call the remote XXX method just like the local method.