The introduction

With the rapid development of Web technology and mobile devices, Hybrid technology has become one of the most mainstream and common solutions. A good Hybrid architecture scheme can make the App not only have the ultimate experience and performance, but also have the flexible development mode of Web technology, cross-platform capability and hot update mechanism. 😄. This series of articles is a summary of the company’s practice in this area, including principle analysis, scheme selection and implementation, practice optimization and other aspects.

You can discuss it with me on Github!

The second actual combat

Existing hybrid solutions

Hybrid App, commonly known as Hybrid application, is a mobile application developed by combining Native technology and Web technology. There are three popular hybrid schemes, mainly based on the differences in UI rendering mechanism:

  1. The basic solution based on WebView UI has been adopted by most mainstream apps in the market, such as wechat JS-SDK, which completes two-way communication between H5 and Native through JSBridge, thus giving H5 a certain degree of Native capability.

  2. Native UI based solutions, such as React-Native and Weex. On the basis of giving H5 Native API capability, the Virtual DOM parsed by JS is further passed to Native through JSBridge and Native rendering is used.

  3. In addition, there is a relatively popular small program scheme recently, which is also through more customized JSBridge and the use of dual WebView dual-thread mode to isolate JS logic and UI rendering, forming a special development mode, strengthening the mixing degree of H5 and Native, improving the page performance and development experience.

The above three solutions are all communication layers based on JSBridge. In fact, the second and third solutions can be seen as continuing to improve the mixing degree of applications through different new technologies on the basis of the first solution. Therefore, JSBridge is also the most critical part of the whole hybrid application. For example, we use JS-SDK when setting wechat sharing, and WX object is the most common JSBridge:

Scheme selection

In fact, the selection of any technical solution should be based on the use of scenarios and existing conditions. Based on several considerations of the current situation of the company, we further optimize the first plan to better suit our needs.

  • Web technology needs the characteristics of rapid iteration, flexible development and online hot update mechanism.

  • The core capabilities of the product are powerful photo taking and underlying image processing capabilities. Therefore, the simple H5 technology can do very limited things and cannot meet the needs. Therefore, it is necessary to strengthen H5 through Hybrid technology.

  • In our business, we don’t have very complex UI rendering requirements, and the series of native UI components in the App are very mature, so we don’t have a strong need for a solution like RN.

Therefore, how to make use of H5’s powerful development and iteration capabilities, give H5 strong underlying capabilities and user experience, and reuse existing mature Native components, has become our biggest demand point — a complete and powerful Hybrid technology architecture solution. 😠

Principle of Hybrid technology

The essence of a Hybrid App is to use a WebView as a container to directly host Web pages in a native App. Therefore, the core point is the two-way communication layer between Native end and H5 end. In fact, it can be understood that we need a set of cross-language communication scheme to complete Native(Java/ Objective-C /…). Communication with JavaScript. This solution is called JSBridge, and the key to the implementation is the WebView as the container, and everything is based on the WebView mechanism.

(1) JavaScript notification Native

Based on the WebView mechanism and open API, there are three common ways to implement this functionality:

  • In fact, the principle of API injection is that Native gets JavaScript environment context and directly mounts objects or methods on it, so that JS can be directly invoked. Android and IOS respectively have corresponding mounting methods.

  • Prompt /console/ Alert interception in WebView, often using Prompt, because this method is used less frequently in the front end, less conflict;

  • WebView URL Scheme jump interception;

The principles of the second and the third mechanisms are similar, and they all intercept the bubble transmission of WebView information to achieve communication. Next, we mainly elaborate the third scheme — URL interception scheme from five aspects: principle – custom protocol – interception protocol – parameter passing – callback mechanism.

1. Implementation principle

The client can monitor and capture network requests made in the WebView

2. Protocol customization

We need to formulate a set of URL Scheme rules. Usually our requests will start with the corresponding protocol, such as the common xxx.com or file://1.jpg, which means different things. Here we can customize the protocol type request as follows:

xxcommand://xxxx? param1=1&param2=2

Here are a few things to note:

(1) xxCommand :// it is just a rule, which can be formulated according to business to make it have meaning. For example, we define xxCommand :// it is common for all apps of the company, and it is common tool agreement:

xxcommand://getProxy? h=1

While defining XXAPP :// separate business protocol for each App.

xxapp://openCamera? h=2

Different protocol headers have different meanings, which makes it clear what scope each protocol applies to.

(2) Do not use location.href here, because the problem with its own mechanism is that multiple concurrent requests will be merged into one, causing the protocol to be ignored, and the concurrent protocol is actually a very common function. We will send the request by creating an iframe.

(3) Usually considering the security, it is necessary to set the domain name whitelist or restriction in the client, to avoid the company’s internal business protocol directly invoked by the third party.

3. Protocol interception

A client can intercept a WebView request using the API:

  • IOS: shouldStartLoadWithRequest

  • Android: shouldOverrideUrlLoading

When the URL header of the request is resolved to the specified protocol, it does not initiate the corresponding resource request. Instead, it parses parameters and calls related functions or methods to complete the mapping of protocol functions.

4. Protocol callback

Since the nature of the protocol is to send a request, which is an asynchronous process, we need to handle the corresponding callback mechanism. Here we use the JS event system, here we will use window.addeventListener and window.DispatchEvent these two basic APIS;

  • 1. When sending the protocol, register the user-defined event with the unique identifier of the protocol and bind the callback to the corresponding event.

  • 2. After completing corresponding functions, the client calls the Dispatch API of the Bridge to directly carry data to trigger user-defined events of the protocol.

Using the event mechanism will make the development more consistent with our front-end habits. For example, when you need to listen for notifications from the client, you only need to listen through addEventListener.

Tips: One thing to note here is that you should avoid multiple binding of events, so when the unique identifier is reset, you need to removeEventListener the event corresponding to it.

5. Parameter passing mode

Because webViews have a limit on the length of urls, the conventional approach of passing the search parameter can cause truncation if the parameter is too long, such as base64 or a large amount of data.

So we need to make new rules for parameter passing. We use function calls. The principle here is based on:

Native can call JS methods directly and get the return value of the function directly.

We only need to mark each protocol with a unique identifier and store the parameters in the parameter pool. Then the client can obtain the corresponding parameters from the parameter pool through the unique identifier.

(2) Native notifies Javascript

Since Native can be counted as the host of H5, it has more privileges. As mentioned above, Native can execute Js code directly through the WebView API. Such access also makes communication in this direction very convenient.

  • IOS: stringByEvaluatingJavaScriptFromString
// Swift
webview.stringByEvaluatingJavaScriptFromString("alert('NativeCall')")
Copy the code
  • Android: loadUrl (4.4 -)
// Call the jsbridge-trigger method in js
// The downside of this method is that it cannot retrieve the return value of the function;
webView.loadUrl("javascript:JSBridge.trigger('NativeCall')")
Copy the code

Tips: When the system is lower than 4.4, evaluateJavascript cannot be used, so simply using loadUrl cannot obtain JS return value. At this time, we need to use the aforementioned prompt method for compatibility, and let H5 end send data through Prompt. The client intercepts and retrieves the data.

  • Android: evaluateJavascript (+ 4.4)
// After 4.4+, use this method to call and get the return value of the function;MWebView. EvaluateJavascript ("javascript:JSBridge.trigger('NativeCall')".new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        // Here is the result returned by js}});Copy the code

Based on the above principles, we have understood the most basic principles of JSBridge, and can implement Native <=> H5 two-way communication mechanism.

(3) Access to JSBridge

Next, let’s take a look at the resources we need in our code. As can be seen from the figure above, the implementation of this scheme can be divided into two parts:

  • JS part (Bridge): Inject the implementation code of bridge in JS environment, including some basic functions such as protocol assembly/send/parameter pool/callback pool, etc.

  • Native part (SDK): Function mapping code of bridge in the client, realizing URL interception and parsing/injection of environment information/general function mapping and other functions.

Our approach here is to encapsulate the two parts together into a Native SDK, which is introduced uniformly by the client. When a client initializes a WebView and opens a page, if the address of the page is in the whitelist, it will inject the corresponding Bridge. This approach has the following benefits:

  • The code of both sides is maintained uniformly to avoid version splitting. When there is an update, as long as the client updates the SDK, there will be no version compatibility problems;

  • App access is very convenient, just need to access the latest version of SDK according to the document, you can directly run the whole Hybrid scheme, easy to quickly landing in multiple apps;

  • The H5 side needs no attention, which makes it easier to open the Bridge to third-party pages.

One thing to note here is that the protocol invocation must be made sure to execute after a successful injection of Bridg.js. Since the injection behavior of the client is an additional asynchronous behavior, it is difficult to capture the exact completion time from the H5 side. Therefore, it is necessary to notify the H5 side based on the above event callback mechanism after the completion of the page monitored by the client. Window.addeventlistener (‘bridgeReady’, e => {}) is used to initialize the page.

(4) Access mode of H5 in App

There are usually two ways to connect H5 to an App:

(1) Online H5, which is the most common one. We only need to deploy the H5 code to the server, as long as the corresponding URL address to the client, open the URL with WebView, can be embedded. The advantages of this approach are:

  • Strong independence, there is a very independent development/debugging/update/on-line ability;
  • If the resources are placed on the server, the package size of the client will not be affected at all.
  • Low access cost, full thermal update mechanism.

However, this approach also has its drawbacks:

  • Totally dependent on the network, the page cannot be opened when offline;
  • The loading speed of the first screen depends on the network. When the network is slow, the loading speed of the first screen is slow.

In general, this approach is more suitable for lightweight pages, such as help pages, tips pages, use guides, etc. These pages are characterized by low functionality, less need for complex functional protocols, and no need for offline use. This method will also be used in some third-party page access, for example, our page calls wechat JS-SDK.

(2) Built-in package H5, which is a localized embedding method. We need to package the code and deliver it to the client, and then the client directly decompress it into the local storage. Usually we use it for some large and important modules. Its advantages are:

  • Because of its localization, the first screen loading speed is fast, and the user experience is closer to the original;
  • Can not rely on the network, offline operation;

But at the same time, its disadvantages are also very obvious:

  • The development process/update mechanism is complicated and requires the cooperation of the client and even the server.
  • The App package size will be increased accordingly.

These two access methods have their own advantages and disadvantages, and should be selected according to different scenarios.

conclusion

This paper mainly analyzes the current development status and basic principles of Hybrid App, including

  • Notify Native JavaScript
  • Native inform Javascript
  • JSBridge access
  • H5 access

Only after understanding its most essential implementation principle, can this scheme be implemented and further optimized. Next, based on the above theory, we will continue to discuss how to implement the real code of this scheme and scheme optimization scheme, please continue the second practical article. Welcome to discuss! For more posts, check out our official account below or go to Github. Thank you! 😊