Mobile Development 13 min read

Understanding JSBridge in Hybrid Mobile App Development

JSBridge is a bidirectional communication layer that lets hybrid mobile apps combine native performance with web flexibility by allowing JavaScript to invoke native functions and native code to call back into the WebView, using techniques such as URL schemes, injected APIs, and platform‑specific evaluateJavascript methods.

HelloTech
HelloTech
HelloTech
Understanding JSBridge in Hybrid Mobile App Development

Hybrid (or mixed) application development combines native code with WebView to leverage both native performance and the flexibility of web technologies. A key challenge in this model is establishing two‑way communication between the H5 (HTML5) layer and the native layer. JSBridge is a widely used mechanism that provides this communication channel.

Hybrid Development Overview

Hybrid development involves two major technology stacks: native (iOS, Android) and web (HTML5). Native code offers high performance and full device capabilities, while web code enables rapid updates and cross‑platform reuse. By integrating the two, developers can enjoy the advantages of both.

JSBridge Concept and Role

Acts as a communication bridge between web and native code, allowing bidirectional calls and data exchange.

Enables JavaScript to invoke native functions such as camera access, notifications, or hardware interaction.

Supports callbacks so native code can notify JavaScript of operation results.

Why JSBridge Is Important in Hybrid Apps

Facilitates cross‑platform development by letting a single web codebase run on multiple platforms while still accessing native features when needed.

Extends native capabilities, improving user experience.

Provides a flexible, extensible way to add new native functions without rebuilding the entire app.

Native → Web Communication

On Android, evaluateJavascript can execute JavaScript and receive a result via a callback:

String jsCode = String.format("window.showWebDialog('%s')", text);
webView.evaluateJavascript(jsCode, new ValueCallback
() {
    @Override
    public void onReceiveValue(String value) {
        // handle result
    }
});

On iOS, WKWebView provides evaluateJavaScript:completionHandler: :

[webView evaluateJavaScript:@"执行的JS代码"
  completionHandler:^(id _Nullable response, NSError * _Nullable error) {
      // handle response
}];

Web → Native Communication

Two common approaches are used:

URL Schema : The web page navigates to a custom URL (e.g., hellobike://showToast?text=hello ). The native side intercepts the request, parses the scheme, and invokes the corresponding native method.

Injecting JS API : Native code injects a JavaScript object into the WebView’s global scope (e.g., window.NativeBridge ) so that JavaScript can call window.NativeBridge.showNativeDialog('hello') directly.

Android injection before API 4.2 used addJavascriptInterface (which had security issues); after 4.2, @JavascriptInterface is recommended. iOS uses UIWebView with JavaScriptCore (iOS 7+) or WKWebView with WKScriptMessageHandler (iOS 8+).

Example of Android injection:

// Inject global JS object
webView.addJavascriptInterface(new NativeBridge(this), "NativeBridge");

class NativeBridge {
    private Context ctx;
    NativeBridge(Context ctx) { this.ctx = ctx; }
    @JavascriptInterface
    public void showNativeDialog(String text) {
        new AlertDialog.Builder(ctx).setMessage(text).create().show();
    }
}

Calling the injected method from JavaScript:

window.NativeBridge.showNativeDialog('hello');

H5 Implementation Details

A typical implementation defines an AppBridge class that encapsulates two main responsibilities: sending requests to native code and handling native callbacks.

Key steps:

Define a JavaScript class/object that provides bridge methods.

Initialize a callback handler that receives data from native and resolves/rejects the corresponding Promise.

Expose a callNative method that packages the class map, method name, parameters, and a unique callback ID, then sends the JSON string to the native side (via URL schema, injected API, or platform‑specific bridge).

Handle the native response, match it with the stored callback ID, and resolve or reject the Promise accordingly.

Example of the callNative implementation (TypeScript‑style):

// Define a method to call native functions
callNative
(classMap: string, method: string, params: P): Promise
{
    return new Promise((resolve, reject) => {
        const id = v4(); // generate unique callback ID
        this.__callbacks[id] = { resolve, reject, method: `${classMap} - ${method}` };
        const data = {
            classMap,
            method,
            params: params === null ? '' : JSON.stringify(params),
            callbackId: id,
        };
        const dataStr = JSON.stringify(data);
        if (this.env.isIOS && isFunction(window?.webkit?.messageHandlers?.callNative?.postMessage)) {
            window.webkit.messageHandlers.callNative.postMessage(dataStr);
        } else if (this.env.isAndroid && isFunction(window?.AppFunctions?.callNative)) {
            window.AppFunctions.callNative(dataStr);
        }
    });
}

Bridge callback initialization:

private initBridgeCallback() {
    const oldCallback = window.callBack;
    window.callBack = (data) => {
        if (isFunction(oldCallback)) oldCallback(data);
        console.info('native callback', data);
        const { callbackId } = data;
        const callback = this.__callbacks[callbackId];
        if (callback) {
            if (data.code === 0) {
                callback.resolve(data.data);
            } else {
                const error = new Error(data.msg) as Error & { response: unknown };
                error.response = data;
                callback.reject(error);
            }
            delete this.__callbacks[callbackId];
        }
    };
}

Usage examples include opening a WebView, invoking OCR services, etc., all through the unified callNative API.

Overall, JSBridge provides a standardized, platform‑agnostic way to achieve seamless interaction between web and native components in hybrid mobile applications.

mobile developmentHybrid AppiOSJavaScriptAndroidWebViewNative IntegrationJSBridge
HelloTech
Written by

HelloTech

Official Hello technology account, sharing tech insights and developments.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.