Introduction to the design and implementation of Hybrid technology article 3-Introduction to the implementation of hybrid technology

Source: Internet
Author: User

Introduction to the design and implementation of Hybrid technology article 3-Introduction to the implementation of hybrid technology

Next article: (before reading this article, read the first two articles)

Design and Implementation of Hybrid technology

Introduction to the design and implementation of Hybrid technology

According to the previous introduction, you should have some simple understanding of the interaction between the front-end and Native. Many friends will think that the interaction is very simple, but it is not difficult, in fact, there is really nothing to say about the interaction between Native and the front-end, but it is not easy to implement a complete Hybrid Project, there are a lot of things to consider. From this interaction protocol alone:

① URL Schema

② JavaScriptCore

In addition, a Hybrid project should have the following features:

① Good scalability -- rely on good conventions

② High development efficiency-dependent on public services

③ Good interaction experience-compatibility issues need to be solved

We will discuss how to implement a Hybrid Project in our actual work and how to promote a project. This is what we will discuss and hope to help you.

This article is my personal development experience. I hope it will be useful to you andSupport Discussion, Pointing outInsufficientAnd some of yourSuggestions.

Design blog


IOS blog


Android blog



Because IOS cannot scan the QR code to download it, you can download it yourself and use the simulator to see it. Next we will start today's content.

In the first chapter, let's take a look.

Details are designed in chapter 2. If you are interested

This chapter focuses on patching.

Boundary Problems

Before using the Hybrid technology, we should pay attention to a boundary problem. We should clarify which project is suitable for Hybrid and which project is not suitable. The project suitable for Hybrid is:

① More than 60% of businesses are H5

② Apps with certain requirements on updates (development efficiency)

Hybrid technology is not suitable for the following projects:

① Only less than 20% of businesses use H5

② High Interaction performance requirements (more animations)

There are applicable scenarios for any technology. Do not think about replacing existing APP businesses with H5. In the end, it will prove that it is self-defeating. Of course, if you only want to embed new experimental services in the APP, this is okay.

Interaction conventions

Based on previous learning, we know that there are two types of interaction with Native:

① URL Schema

② JavaScriptCore

The two methods have their own advantages and disadvantages. First, the URL Schema is stable and mature. If you use the "ajax" interaction method mentioned above, it will be more flexible; from the design point of view, JavaScriptCore seems more reasonable, but we find that the injection time is not guaranteed in actual use.

When iOS colleagues inject JavaScriptCore, our original intention is to inject all Native capabilities before loading the webview, but the actual situation is that the page js has been executed before being injected, this will cause Hybrid interaction to fail. If you see a Hybrid platform that suddenly shows incorrect headers, it may be caused by this problem, so the JavaScriptCore will be discarded.

Problems caused by JavaScriptCore: ① The injection time is not unique (maybe a BUG) ② when the page is refreshed, the injection of JavaScriptCore is inconsistent among different models, and some of them are not injected at all, therefore, all hybrid interactions are invalid.

If you have to use JavaScriptCore, we have made a compatible solution to solve this problem. We use the URL Schema method to execute a command at the beginning of page logic loading and reload native methods, for example:

1 _.requestHybrid({2     tagname: 'injection'3 });

This can solve some problems, but some methods that will be used immediately after initialization may not work, such:

① Obtain the geographical information given by native

② Obtain the user information provided by native (obtained directly using variables)

As for production, we are still striving for stability, so we finally chose the URL Schema.

After understanding the basic boundary issues and selecting the underlying interaction mode, we can start a preliminary hybridgeid design. However, this is a method that can be used for production, it is far from the implementation of the Hybrid solution.

Account System

Generally, a company's account system is robust and flexible, which reflects the overall strength of the R & D team to a large extent:

① Unified authentication

② Process the graphic verification code of the SMS Service

③ Permission Design of subsystems and export of public user information

④ Third-party access solution

⑤ Access Document Output

6 ......

Whether this technical solution is one thing (indicating that there is no way of thinking), how many sets of solutions are one thing (indicating that the technology is chaotic and the technology is not uniform), and to what extent the external solution is achieved, of course, this is not the focus of our discussion, and the account system is also an indispensable part of Hybrid design.

The account system involves interface permission control and Resource Access Control. Currently, there is a solution that the front-end code does not perform interface authentication, and all the work of an account is put on the native end.

Native proxy request

If H5 wants to do an old App business, all the APP80 % or more businesses are Native. Such apps have not considered H5's feelings in terms of interfaces, A lot of information is required, such:

① Device No.

② Geographic Information

③ Network conditions

④ System Version

There are a lot of public information that H5 cannot obtain or is not easy to obtain, because H5 is often engaged in some small businesses, such as personal homepages and other unimportant businesses, the Server may not be willing to provide additional interface adaptation, but using additional interfaces may also break some of their unified rules. In addition, native has its own set of public processing logic for interfaces, therefore, the Native proxy H5 request scheme is launched, and the public parameters are automatically taken by Native.

1 // only focus on hybrid debugging for the time being, followed by three-end matching 2 _. requestHybrid ({3 tagname: 'apppost', 4 param: {5 url: this. url, 6 param: params 7}, 8 9 callback: function (data) {10 scope. baseDataValidate (data, onComplete, onError); 11} 12 });

This solution has some advantages. The interfaces are uniform, and the front-end does not need to pay attention to interface permission verification. However, this will bring a nightmare to the front-end!

Compared with native, The frontend has a great advantage in that it has flexible debugging. This proxy request method will restrict the request to take effect only in the APP container, causing great pain for front-end debugging.

In terms of actual production results, efficiency is also very affected, which may cause the front-end to no longer be willing to do the APP business in the future. Therefore, exercise caution when using the APP ......

Cookie Injection

The common front-end permission signs are still made with cookies. Therefore, Hybrid's mature solution is still to inject cookies, one premise here is that native & H5 has a unified account system (a unified permission verification system ).

Because the webview used by H5 can have an independent login state, it is too messy to maintain without restrictions, such:

We open Ctrip's website in the qq browser. Third-party login on the Ctrip site can call up qq, and then the login is successful. After the qq browser is complete, there is also a login status, but no login is found, clicking one-click logon triggers qq logon again.

Of course, qq, as a browser container, should not focus on business login. It is okay to do so, but if one of our H5 sub-applications is logged on, we want to synchronize the login state to native. If native monitors cookie changes, it will be too complicated. The general solution is:

In the Hybrid APP, all logins go through the logon boxes provided by Native.

Each time webview native is opened, the current logon information is written into the cookie, and the frontend is logged on. The logon box is invoked at the interface for unified processing:

1/* 2 whether successful or not, the logon box will be closed. 3 parameters include: 4 callback for successful success logon 5 callback for failed error logon 6 url if success is not set, or, if no true is returned after success is executed, the system will jump to this url 7 */8 HybridUI by default. login = function (opts) {9}; 10 // => 11 requestHybrid ({12 tagname: 'login', 13 param: {14 success: function (){}, 15 error: function () {}, 16 url :'... '17} 18}); 19 // consistent with the logon interface, parameter 20 HybridUI. logout = function () {21 };
Account Switch & logout

There is no need to pay attention to account cancellation, but because H5 pushes webview pages one by one, how to deal with these pages after logon is a problem.

What we designed here is that once you log on again or log out of your account, all webviews will be pop up, and then a new page will be opened, so there will be no weird page display problems.

Public Business Design-systemization

In the Hybrid architecture (even in traditional businesses), many public services exist. Many of these public services are implemented by H5 (such as registration, address maintenance, and feedback, login is a native Public Service). If we need a Hybrid architecture with high real efficiency, we have to do a good job of all kinds of public services. Otherwise, H5 alone will do business, efficiency may not be much higher than Native.

After the underlying framework is complete and unified, You can restrict business development with the power of standardization. The public business developed under the unified framework will greatly improve the overall work efficiency. Here we take registration as an example, A public page is designed as follows:

Public Service Code should allow users to customize pages on URL parameters. Here, URL parameters are generally unique and overwritten. This design is applicable to native pages.

The URL contains the following parameters:

① _ Hashead indicates whether there is a head. The default value is true.

② Whether hasback contains the rollback button. The default value is true.

③ The text of the backtxt rollback button, which is not displayed by default. It is displayed as the rollback icon.

④ Title

⑤ _ Btntxt button text

⑥ Jump when the backurl rollback button is clicked. If it is null by default, history. back is executed.

7_successurl: Required

As long as the public page is designed like this, it can meet the needs of most businesses. At the underlying layer, it is easy to use a set of code for both native and H5. Here is another example:

If we want to click "success" and go to a native PAGE, if each of our Native pages has been URL-based according to our previous design, we can jump in this direction:

1 requestHybrid({2     tagname: 'forward',3     param: {4         topage: 'nativeUrl',5         type: 'native'6     }7 });

This command will generate a url like this:

_ Successurl = hybrid: // forward? Param = % 7B % 22 topage % 22% 3A % 22 nativeUrl % 22% 2C % 22 type % 22% 3A % 22 native % 22% 7D

When you click callback, an H5 URL jump will be executed:

window.location = _successurl

According to our previous hybrid specification, this kind of request will be intercepted by native, So we jumped to the desired native PAGE. the whole set of things is what we call systemization:

Offline update

According to the previous conventions, if there are static resources in Native, they are also divided by channel:

Webapp // root directory ├ ── flight }── hotel // hotel channel │ index.html // business portal html resources. If it is not a single-page application, there will be multiple portals │ main. js // package all js resources of the Business │ └ ── static // │ ── css │ ├ ── hybrid // Native Header icon of the storage service customization class │ └ ── images ─ ── libs │ libs. js // All js resources of the framework are packaged │ └ ── static // framework static resource Style File ├ ── css └ ── images

We create a rule here. native will filter requests of a rule and check whether the file exists locally. If there is a local file, it will directly read the local file, for example, we will map this type of requests to the local machine:>>file ===> flight/static/hybrid/icon-search.png

In this way, the browser will continue to read online files. In native, if there are local resources, the local resources will be read:

However, we encountered some problems in actual use cases.

Increment Granularity

In fact, we considered a lot of problems when we first designed the incremental design. But in actual business, what we made is often very simple due to the oppression of time. This can only be iterated slowly, all of our caches have two considerations:

① How to store and read Cache

② How to update Cache

The browser's cache reads and updates are relatively simple:

The browser only needs to read the latest cache.

In the case of an APP, there will be a situation where the newly released APP wants to read the offline package, while the old APP does not want to read the incremental package (the old APP does not support the incremental package downloaded ), in more complex cases, if you want to fix a specific version, you need to issue the incremental package in a targeted manner. This makes the situation complex, and the complexity is an error, we can often solve complicated scenarios with simple conventions.

Consider the following scenarios:

Our APP is about to release a new version. We have allocated the static resources of the first version. When the review is complete, our old version of APP suddenly has a temporary demand to go online, I know it sounds a little nonsense, but this nonsense actually happened. If we hit the incremental package at this time, so the latest APP will pull this code during the review, but maybe this is not what we expected, so we have the following agreement with native:

The Native request carries the version number when performing incremental updates, and forces the conventions to be consistent with the large version number of iOS and Android. For example, if iOS is 2.1.0Android, the BUG fix may be 2.1.1 but not 2.2.0.

Configure a complex version ing table on the server:

# Appendix 1 // project configuration const APP_CONFIG = ['surgery '=> [// package name 'channel' => 'd2d ', // main project channel name 'dependencies' => ['Blade ', 'static', 'user'], // The dependent channel 'version' => [// The range of incremental packages corresponding to each version. The maximum number of incremental packages in the range is obtained. '2. 0. x' => ['gte' => '1. 0.0 ', 'lt' => '1. 1.0 '], '2. 2. x' => ['gte' => '1. 1.0 ', 'lt' => '1. 2.0 '], 'version _ I' => [// a version that requires special configuration for ios], 'version _ a' => [// a version with special configuration required for Android];

The read restrictions of the APP version are solved here. After we finish, we need to care about the incremental arrival rate and update rate. We will also worry that our APP will read the wrong file.

Update Rate

What we sometimes want is that once the incremental package is released, users can immediately see the latest content with their mobile phones. In this way, the app calls the incremental package more frequently, therefore, we set an update check every 30 minutes.

Read correctly

It may be a bit worrying here, because the Native program is not developed by hand, and it is always worried that the APP will read static files when pulling the incremental package or extracting the package. Will it read errors, after thinking about it, we will continue to use the md5 packaging method to package the files in the html to be implemented as md5 references. If the landing page is downloaded, if you cannot read the local file, you can pull online resources.

A Hybrid project must meet the frontend development habits to the maximum extent and provide debuggable solutions.

As we have said before, the biggest problem for directly sending all requests with native is that debugging is inconvenient, and the correct development of hybrid should have more than 70% of the time, pure business developers do not need to care about native joint debugging. After all business development is completed, simply tune it in.

Because the test environment resources need to be read during debugging, the server-side qa interface must have a global switch to disable all incremental reads.

Many people have already introduced the method of Agent debugging. I will not talk about it here. Let's talk about some debugging schemes in native. In fact, many people know it.


First, you need to have a Mac machine and then enable safari. In preference settings, enable the development mode:

Start the simulator and start debugging:


Android requires FQ chrome, and then enter chrome: // inspect/# devices, provided that native colleagues enable the debugging mode for you. Of course, Android can also use the simulator, however, the Android real machine performance is too different. We recommend that you use a real machine for testing.

Use swift for some pitfalls

Apple officially launched swift, so our iOS team was very good at trying it and quickly promoted it within the team. The size of our OC itself was originally more than 0.1 million lines of code, we all know the truth:

Rebuilding the project's tornado

During the reconstruction process, some historical problems, or some third-party libraries, the code will always have a little bit of redundancy, and I don't know whether swift is an official problem or what is going on, A little more changes are required each time.Compile for more than an hour!!!! You are not mistaken. It takes more than an hour to compile.

One time, my friend was playing a game and I said two things. He said that he was compiling, and Nima scolded him with disdain. Later, when I started to call iOS, compiled for 2 hours !!! Since then, I have lost my temper when I saw him play games !!!

This kind of compilation feeling is like eating a bad stomach, squatting in the toilet for a long time, but nothing is pulled out !!! So switch all to swift.

If there is a certain amount of historical business or new business, it is best not to fully use the new technology, immature technology, if there is any irreversible pitfall, then there will be no retreat.
IOS static resource Cache

Android has a global switch that controls the static resources to read the cache. However, this switch has not been found for a long time in iOS, and it is particularly powerful in reading the cache, therefore, it is best to add a timestamp or md5 when all request resources have incremental packages.

Android webview compatibility

Android webview is not performing well and has many problems such as pop-up screens. The following problems are encountered:

① Use the hybrid command (for example, jump). If you click quickly, Android will open two new pages due to slow response, and you need to freeze consecutive clicks.

② In earlier versions below 4.4, js callback cannot be captured. This means that Android cannot get the js return value, and some special functions cannot be done, such as back fault tolerance.

③ ......

Some minor features

In order to make H5 more like native, we will agree on some small features. This feature is not suitable for general architecture, but it will have more highlights.

Rollback update

In fact, every time we jump in hybrid, we open A new webview. When A-> B, in fact A is only hidden. When B clicks back, A will be displayed directly, and A will not make any updates, which is imperceptible to the front-end.

In fact, this is an optimization. To solve this problem, we have made a pull-down refresh feature:

1 _. requestHybrid ({2 tagname: 'headerrefresh', 3 param: {4 // The text 5 title: '000000' 6} displayed in the drop-down list, 7 // The callback executed after the drop-down, refresh all the brute force attacks. 8 callback: function (data) {9 location. reload (); 10} 11 });

However, this is not always comfortable with automatic refresh, So we agreed on these events when loading the page for the first time:

1 // register the page to load event 2 _. requestHybrid ({3 tagname: 'onwebviewshow', 4 callback: function () {5 6} 7}); 8 // register the shadow event 9 _. requestHybrid ({10 tagname: 'onwebviewhide ', 11 callback: function () {12 scope. loopFlag = false; 13 clearTimeout (scope. t); 14} 15 });

This is triggered when webview is displayed, and when webview is hidden, so that the user can perform automatic data refresh. However, to do partial refresh, it depends on the development schedule, good technology, more time, more natural experience.


According to our previous conventions, the header is quite regular. However, due to product and visual force, we implemented a different header. Although we were not happy at first, it feels okay after you have done it ......

This workload is mainly native, and we only need to agree:

1 this. header. set ({2 view: this, 3 // left button 4 left: [], 5 // right button 6 right: [{7 tagname: 'cancel', 8 value: 'cancel', 9 callback: function () {10 this. back (); 11} 12}], 13 // searchbox custom 14 title: {15 // special tagname16 tagname: 'searchbox', 17 // title, this data is the default text box text 18 title: 'cancel', 19 // when there is no text, the placeholder prompt 20 placeholder: 'search Hospital, department, Doctor, and illness ', 21 // whether to enter the page by default to get focus 22 focus: true, 23 24 // The callback event related to the text box 25 // data is a json string 26 // editingdidbegin is a point Event 27 triggered when you press or the text box gets the focus // editingdidend is the event triggered when the text box loses the focus 28 // editingchanged is the event 29 type: ''triggered when the text box data changes :'', 30 data: ''// true data 31}, 32 callback: function (data) {33 var _ data = JSON. parse (data); 34 if (_ data. type = 'editingdidend' & this. keyword! = $. Trim (_ data. data) {35 this. keyword = $. trim (_ data. data); 36 this. reloadList (); 37} 38 39} 40 });

I hope this article will help some friends who are going to contact the Hybrid technology. Here is the last practical article about the Hybrid series. Here is some of the articles during the demo, the code of the git library will be sorted out later:


Implementation Project

The actual business is medical Unicom. If you are interested, try:

Push sentiment

It has taken three months from project research to project implementation to the latest optimization. It is not easy to do one thing well, and we also involve continuous optimization, and supporting services such:

① Passport

② Wallet Business

③ Feedback business


The meaning or role of many jobs is invisible to non-technical colleagues, but if we don't stick to it, we will be overwhelmed by business pressure or self-indulgence, so there's nothing to do. We need to push one thing. It's impossible to say it when we come out. Hey, look, we're good. You can use it, in this way, people will doubt you. We must first make a demo to make people have a certain initial impression, and then force or secretly try out a production business. On the one hand, we can get technical dependencies, on the one hand, I want to tell other colleagues that it doesn't cause much problems.

It is hard to do things, to promote things, to stick to things, and to work together with each other. here we need to believe in it. In particular, we would like to thank the team's three partners for their selfless efforts (Yang, Wen, and Wen ).

In the future, we will continue to promote the construction of hybrid while trying to React Native to find a better solution for ourselves.


At last, I have very few Weibo fans. If you think this blog is helpful to you, I would like to ask my blog to like it !!!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.