“Live up to the time, the creation of non-stop, this article is participating in 2021 year-end summary essay competition”
What is a JSBridge
As we all know, native APP development has a webview component (webview for Android, UIWebview for iOS7 and up, WKWebview for iOS7 and up) that can load Html files.
Before THE Html5 boom, loaded Html was often only used to do some simple static resource display, but after the popularity of H5,Html5 has a lot of new features, cool effect, especially in iOS H5 support has been very good,Android 4.4 The above support is sufficient, so at this time I found that some major logic can be written with H5 pages, and then directly load and display with webView native, which greatly improves the development efficiency, one development, both ends (Android, ios) common, and experience is very good.
JSBridge is the communication bridge between H5 and Native, which allows H5 to call the Native API (such as taking photos, capturing and recording screens), greatly expanding the functions of H5.
Communication principle
The principle of JSBridge communication mode can be summarized with a picture and a sentence, that is
H5-> somehow triggers a URL ->Native captures the URL for analysis ->Native does the processing ->Native calls H5’s JSBridge object to pass the callback
The url scheme is introduced
- Url scheme is a link similar to URL, which is designed to facilitate apps to call each other directly
Specifically, you can use the OpenURI of the system to open a link similar to a URL (parameters that can be spelled in), and then the system will judge. If it is the url scheme of the system, open the system application; otherwise, you can check whether there is any app registered with such scheme and open the corresponding APP
It should be noted that this scheme will take effect only after the native APP is registered. For example, wechat scheme is (weixin://).
- Our URL scheme in JSBridge is one way to emulate the above form
Specifically,app will not register the corresponding scheme, but the front-end page triggers scheme in some way (such as using iframe.src), and then Native captures the corresponding URL triggering event in some way, and then gets the current triggering URL. According to the defined protocol, it analyzes which method is currently triggered, and then root Perform, etc by definition
JSBridge design idea
Now that we’ve covered the principles of JSBridge, what does it take to design a JSbrDige object
The key idea
- Design a global bridge object Native to interact with JS
- How does JS call Native
- How does Native know when an API is called
- Analyze the format of URL-parameters and callbacks
- How does Native call JS
- H5 API method registration and format
Now that we know the overall idea, let’s get started
1. Design a global bridge object that native interacts with JS
- This object is named “JSBridge” and is an attribute of the global object Window on the H5 page
var JSBridge = window.JSBridge || (window.JSBridge = {});
Copy the code
- This object has the following methods
-
- RegisterHandler (String,Function)H5 calls register Native JS methods, which can be called via JSBridge after registration. The call registers the method to the local variable messageHandlers
- CallHandler (String,JSON,Function)H5 calls the native open API, which is actually triggered locally by the URL Scheme. The callback ID is stored in the local variable responseCallbacks when called
-
- _handleMessageFromNative(JSON)Native calls the method registered on the H5 page or notifies the H5 page to execute the callback method
2. How does JS call Native
When executing the callHandler, the following steps are taken internally:
-
Determine if there is a callback function, and if so, generate a callback id and add the ID and corresponding callback to the callback collection responseCallbacks
-
Through a specific parameter conversion method, the incoming data, method name together, into a URL scheme
// The basic useful information is the callbackId,handlerName and data. // The scheme will be analyzed after it is captured natively CUSTOM_PROTOCOL_SCHEME://API_Name:callbackId/handlerName? dataCopy the code
- Scheme is triggered using a hidden IFrame that is already created internally
Var messagingIframe = document.createElement('iframe'); messagingIframe.style.display = 'none'; document.documentElement.appendChild(messagingIframe); // Trigger scheme messagingifame. SRC = uri;Copy the code
Href = window.location.href = window.location.href = window.location.href = window.location.href = window.location.href All previous requests are ignored. Therefore, when the JS side initiates a network request, it needs to use iframe to avoid this problem.
3. How does Native know when an API is called
In the previous step, we successfully triggered Scheme in the H5 page, so how does Native catch scheme being triggered?
Depending on the system,Android and iOS have their own processing methods
Android capture URL scheme
In Android (WebViewClient), shouldoverrideurlLoading captures the triggering of a URL scheme
Public Boolean shouldOverrideUrlLoading(WebView view, String URL){shouldOverrideUrlLoading(WebView view, String URL){ If true, the WebView executes the url return true according to the program; }Copy the code
It is also possible to trigger scheme without iframe.src on Android, but window.prompt(uri, “”); To trigger scheme, and then get the URI in Native by overriding onJsPrompt of WebViewClient
IOS capture URL scheme
In iOS,UIWebView has a feature that all network requests initiated in UIWebView can be notified in the Native layer through the delegate function. In this way, we can capture the url in the webview scheme (principle is to use shouldStartLoadWithRequest) to trigger
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *url = [request URL]; NSString *requestString = [[request URL] absoluteString]; // Get the URL schemeCopy the code
4. Analyze urL-parameter and callback formats
In the previous step,Native has received the method called by JS, so next, the Native should parse the data in the defined data format
The format of url scheme has been mentioned above. After Native receives the URL, it can extract the callback parameter ID, API name and parameter according to this format, and then proceed as follows
-
According to the API name, find the corresponding API method locally, and record the callback function ID after the method is executed
-
According to the extracted parameters, according to the defined parameters to convert if the format is JSON need to be manually converted, if the format is String can be directly used
-
The corresponding API function methods are executed natively
-
{responseId: callback id,responseData: callback data} {responseId: callback id,responseData: callback data}
-
- ResponseId Specifies the id of the H5 page corresponding to the callback function that needs to be executed when the URL scheme is generated in H5
- ResponseData JSON-type callback data that Native needs to pass to H5 is in JSON format: {code:(integer, whether the call succeeded,1 successful,0 failed),result: the specific result information to be passed, can be any type, MSG: some other information, such as the error message when the call error}
-
H5 page callback is notified via JSBridge
5. How does Native call JS
At this point, the Native calls H5’s JS methods via JSBridge or notifies H5 for a callback
// Pass the callback message to H5 JSBridge._handleMessageFromNative(messageJSON);Copy the code
As mentioned above, data is actually transmitted to H5 through JSBridge _handleMessageFromNative, where messageJSON data format is different according to two different types, as follows
Native notifies the H5 page for a callback
Refer to point 4 to notify H5 callback after native function execution is complete
Native actively calls the H5 method
When Native calls H5, the data format is :{handlerName: API name,data: data,callbackId: callbackId}
- HandlerName Specifies the name of the OPEN H5 API that the String needs to call
- Data JSON-type data that needs to be passed, fixed in JSON format (because we fixed H5 registered method to receive the first argument must be JSON, the second callback function)
- CallbackId String indicates the id of the callback function generated natively. After h5 is executed, the url Scheme notifies the native API of the successful execution and passes the parameter
Note that in this step, if the Native API is not registered with H5, there will be an error on the H5 page.
In addition, when H5 calls Native, it must inform H5 to call back in time after Native processing is completed. Otherwise, the callback function will not be automatically destroyed, and memory leakage will be caused if there are too many.
6. Registration and format of API methods in H5
As mentioned above, Native calls API methods registered in H5 actively. How to register API methods for Native calls in H5? What’s the format? The following
API registered for native invocation in H5
// Register a test function JSBridge. RegisterHandler ('testH5Func',function(data,callback){alert(' test function receives data :'+ json.stringify (data)); Callback &&callback(' test return data... '); });Copy the code
Further JSBridge improvement solution……
The general idea is
H5 calls the key steps of Native for separation, changing the previous direct URL scheme to a unified URL scheme, and then Native takes the initiative to obtain the transmitted parameters
Before improvement: H5 called Native-> assembled all parameters into URL scheme-> Native capture scheme for analysis
After improvement: H5 calls Native-> stores all parameters in local array -> triggers a fixed URL scheme-> Native capture scheme-> Native actively obtains parameters through JSBridge -> analysis
Finally attached demo link, like the partners to give a thumbs-up oh ~
To be continued…