preface

Recently, I have been working on the process of independence. I would like to take this opportunity to write down my plan and implementation. The reference article link is also put below, interested partners can kangkang.

background

My side of the business scenario is mainly to open H5 activities in the game. Since the WebView itself takes up a lot of memory, and the game itself has a lot of memory, it takes a lot of extra memory to start the WebView again in the main process, so you want to run the WebView in a separate process so that if the WebView crashes, it doesn’t crash the game. And because WebView is a separate process but still attached to the main process, so a lot of logic in the application needs to be multi-process reuse.

plan

The feasibility of

Why is the independent process solution feasible for me? Because the WebView starts as an Activity in a project, that means you can start a new process when you open the WebView.

Independent process

Congratulations, you’ve opened the independence process. Well, I’m kidding. It’s the easiest step.

Communication mode

The most difficult part of the standalone process solution is the communication between the standalone process and the main process. The project architecture is SPI structure (external API layer, internal IMPL layer) and does not support cross-process communication, so we have to do this ourselves. Since the main interaction between WebView and parties is method calls, we chose to use AIDL as the means of process communication.

In this project, there are many Native method calls for H5, so this article mainly explains from this aspect.

Independent processes are designed so that the WebView process is only responsible for the WebView, so it is more likely that the WebView process will send messages to the main process and return the required data/communication results to the WebView process through the provided AIDL callback interface.

Because of the SPI structure, and in order for the process communication interaction to converge to the IMPL layer (which is not exposed to the outside world), I made the WebView a standalone component, and all access needs to come from the interface exposed by the IWebViewService. The WebView process communicates with the main process through AIDL in WebViewService (IMPL layer).

For details about AIDL implementation, refer to the official documentation and the implementation demo provided in the link at the end of the article.

Uniform method invocation interface

Since H5 has different capabilities for different Native modules, we need to give each module a unified execution interface (Command). In this way, once the unified interface is registered and executed (handleWebAction) (PS: Here I think the original blogger is very clever, to give a unified injection interface, so that the implementation can be implemented in their own modules.

Provides the interface to Command at the API layer

Here are some examples:

private final Command oneMethod = new Command()
        @Override
        public String name(a) {
            return "oneMethod";
        }

        @Override
        public void execute(Context context, Map params, IWebAidlResultCallback resultCallback) {
            try {
                boolean a = (boolean) params.get("a");
                Map res = oneMethod(context, a);
                Log.d(TAG, res.toString());
                resultCallback.onResult(name(), res);
            } catch(Exception e) { Log.d(TAG, e.toString()); }}};Copy the code

Provides methods for registering a Command and executing a Command

Command Manages and schedules internal execution

For details about internal management and scheduling, see the link at the end of the following. Commands at different levels (such as THOSE involving UI and those not involving UI) can be summarized into an abstract command set, and then inherited from the commands at different levels.

CommandsManager is then grouped into the appropriate Command set based on the hierarchy passed in by executing the Command method, and is then unified by Command management.

Finally, the dispatching center CommandDispatcher carries out the execution environment of the command (main process or WebView process) (remember that both processes are the same application here).

Binder connection pool

Before we talk about connection pooling, here’s a diagram of AIDL’s Binder mechanism.

After the main process and WebView process are designed, we need to consider how to connect them together. That is to start Service in the main process and WebView process to bindService.

Stay connected

Keeping the connection alive is as simple as adding binder’s death notification ibinder.deathrecipient to binder’s connection and reconnecting.

Multiple AIDL functional interfaces

Although H5 is used in the project to interact with Native process most frequently, the main process still has some other places that need to listen to WebView state, such as WebView exit, error return of opening link, etc. These are relatively fixed functions that also need inter-process communication, while it seems redundant to declare more than one Service. With this in mind, it is important to think about how services can manage multiple binders.

The concept of a binder connection pool was introduced. A BinderPool is provided through the AIDL interface to provide different AIDL functions.

The WebviewBinderPool proxy class that implements AIDL returns different binderPools for different Bindertypes. Bind the webviewBinderPool in the ServiceonBind procedure.

WebviewBinderPool binderPool = WebviewBinderPool.getInstance(context);
IBinder binder = binderPool.queryBinder(binderType1);
webAidlInterface = IWebAidlInterface.Stub.asInterface(binder);
Copy the code

conclusion

So far, I’ve shown you what I think is important and what needs to be addressed in the WebView standalone process solution. It is best to start the WebView as an Activity, and then as long as the communication between the processes is handled, it is easy to think of a WebView standalone process solution. The advantages of this stand-alone process are obvious, but there are also some adverse disadvantages.

Advantages:

  1. Reduce memory usage for the main game process
  2. – Game progress will no longer crash due to WebView crashes, reducing OOM rate

Disadvantages:

  1. The WebView process’s connection to the main process may fail
  2. When the game uses too much memory, starting the WebView process may cause the main game process to be killed

In view of the disadvantages, in fact, the possibility of connection failure is relatively small, you can add failure reconnect mechanism. The second point is that we need to reduce memory by other means.

OK, so the WebView independent process solution to share to here, finally paste my reference.

References:

Android WebView independent process solution

Android webView independent process communication

Overview of the binding service

Android Interface Definition Language (AIDL)