In the projects I have done so far, the communication between H5 and Android is written one method after another, marked with annotations, and then called each other, and they are all written in the same place, and even some WebView is not put into another process, and there are many methods, which is particularly bloated and chaotic. I wrote a cross-process WebView framework before and improved it after learning. Although there are many points that can be optimized, let’s just write them down for now
Making portal
Making portal
Frame drawing
That’s the relationship between the classes, and that’s pretty much the calling flow
Method of use
Create a Commond directive
A directive is a method, or you can create a generic directive, or you can encapsulate it.
This is introduced with a simple instruction to start an Activity
- First, a Command must inherit Command and implement two methods, CommandName and execute method.
- Second, use the AutoService annotation to indicate that it belongs to the Command. Class for easy lookup (AutoService can be replaced by custom annotations).
- The callback parameter belongs to the AIDL file, and can be used if there is a data callback, but not if there is no data callback
Execute an instruction
The directive is created on the Android side and we wait for the H5 side to call our method
- As follows, if H5 wants to call the instruction created above, it only needs to pass in the instruction name ‘openActivity’ and the parameter message in the method, and the Android terminal can find the corresponding instruction in the local instruction set and perform the corresponding operation according to message
Doesn’t it look cleaner? Only one directive can be written to the same file, can be written separately, or can even create a separate module to store instructions, I feel a lot cleaner than a method with a @javascriptInterface annotation
Analysis of Web calls to Main
The first principle is that AIDL is used, but AIDL is not explained here. There are already a lot of good articles online. But for the sake of understanding, let’s just think about it this way
- AIDL is the man-in-the-middle interface
- Stub implementations implement methods in AIDL
- A Proxy is a remote control, and when you get that object you can call the methods defined in AIDL
The AIDL is like a menu with defined dish names. The Proxy remote can order from the AIDL menu. Stub is like a cook, you order the food, and eventually AIDL tells him to do the implementation
Let’s start with two AIDL files
Two AIDL files
- IWebviewProcessToMainProcessInterface (hereinafter referred to as IWebToM)
This AIDL is simple, with only one method and takes three arguments
These are the instruction name, the parameter carried, and another AIDL object
- ICallbackFromMainprocessToWebViewProcessInterface (hereinafter referred to as CallbackMToWeb)
This is also very simple, a callback function name, and a callback data
Entrance takeNativeAction
This is the entry for H5 to call the Android method. You can see that after converting the data to jsparam.class, it is directly sent to WebCommandDispatcher for processing
WebCommandDispatcher remote control
You can see that an IWebToM object is stored in WebCommandDispatcher and the Service is started
The iWebTom.stub.asInterface (service) method then gets the AIDL Proxy object and the remote control
This means that WebCommandDispatcher can execute the methods defined by IWebToM
That is, calling the handleWebCommand method in the Proxy object
MainCommandsManager Stub implementation class
As you can see, iWebTom. Stub is directly inherited from iWebTom. Stub, and the AutoService annotation used previously is also used here.
She will help us collect by typing up AutoServiceCommand
Flags the class and then saves it
Then when the remote control calls the method, it will call the method we copied, and then search in the collected Command set to find the corresponding instruction execution method
Main calls back to Web analysis
We know that callbacks are done through the AIDL object CallbackMToWeb, so who is the remote control and who is the implementation class?
CallbackMToWeb implementation class
Going back to the methods in WebCommandDispatcher, you can see that a CallbackMToWeb implementation class was passed in when IWebToM’s methods were called
The Stub implementation class will then be passed to a specific directive, and the call will then be returned to the onResult method, which will hand the callback directly to the webView, completing the callback from Main to the Web
Where is the remote control for CallbackMToWeb
If you didn’t see it all the way through the stub.asInterface method to get the remote control, since he can call it, it means that internal conversion for us.
So we go into AIDL, and the system generates the CallbackMToWeb file for us, and we can just click on it and find where it called
In the IWebToM file that the system generated for us, when handleWebCommand is called, it will generate a Proxy object for us and then pass it out, so when we pass a specific instruction, it will already be a Proxy object, and then the whole process will work
At the end
This framework is just a simple framework, because always forget the idea, so make a record. There are still many areas that can be improved, so feel free to point them out in the comments section