Usage Guide: Advanced Setup

This section covers more advanced configuration and integration patterns for JsBridge.

Ensuring the Bridge is Ready in JavaScript

The WebViewJavascriptBridge object is injected into the WebView by the native code after the page begins to load. This process is asynchronous, meaning the window.WebViewJavascriptBridge object may not be immediately available when your script runs.

Attempting to call a bridge function before it's ready will result in an error. To prevent this, you must always wait for the WebViewJavascriptBridgeReady event.

The library's README.md provides a robust helper function to manage this initialization process.

The setupWebViewJavascriptBridge Function

It is highly recommended to copy this function into your JavaScript code and wrap all your bridge interactions within it.

function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) {
        return callback(WebViewJavascriptBridge);
    }
    if (window.WVJBCallbacks) {
        return window.WVJBCallbacks.push(callback);
    }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'https://__bridge_loaded__'; // A convention from the iOS version
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}

Usage Example

By using this function, you can be certain that your code will only execute after the bridge has been successfully initialized.

setupWebViewJavascriptBridge(function(bridge) {
    // All bridge code goes here

    bridge.registerHandler('myJsHandler', function(data, responseCallback) {
        console.log("myJsHandler called with:", data);
        responseCallback({ 'status': 'ok' });
    });

    bridge.callHandler('myJavaHandler', { 'key':'value' }, function(responseData) {
        console.log("Java responded:", responseData);
    });
});

Alternative Integration with BridgeHelper

Instead of using the BridgeWebView class directly, you can integrate JsBridge functionality into your own custom WebView subclass. This is useful if you already have a custom WebView with specific settings or behaviors.

The BridgeHelper class is designed for this purpose.

The example application demonstrates this with CustomWebView.java.

Steps to use BridgeHelper

  1. Create a Custom WebView: Extend the standard Android WebView.
  2. Instantiate BridgeHelper: Create a member variable for BridgeHelper, passing your custom WebView instance to its constructor.
  3. Delegate WebViewClient Calls: In your WebViewClient, you must delegate key methods to the BridgeHelper instance:
    • onPageFinished(): Call bridgeHelper.onPageFinished() to inject the JavaScript bridge file.
    • shouldOverrideUrlLoading(): Call bridgeHelper.shouldOverrideUrlLoading() to allow the helper to intercept bridge-related URL changes.
  4. Expose Bridge Methods: Expose the public methods of BridgeHelper (like registerHandler, callHandler, etc.) through your custom WebView class.

Example: CustomWebView.java

This code from the sample app shows the core integration pattern.

@SuppressLint("SetJavaScriptEnabled")
public class CustomWebView extends WebView implements WebViewJavascriptBridge, IWebView {

    private BridgeHelper bridgeHelper;

    // ... Constructors ...

    private void init() {
        // ... Standard WebView settings ...
        this.getSettings().setJavaScriptEnabled(true);

        // 1. Instantiate the helper
        bridgeHelper = new BridgeHelper(this);

        // 2. Set up the WebViewClient and delegate calls
        this.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView webView, String s) {
                bridgeHelper.onPageFinished();
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String s) {
                return bridgeHelper.shouldOverrideUrlLoading(s);
            }
        });
    }

    // 3. Expose bridge functionality
    public void registerHandler(String handlerName, BridgeHandler handler) {
        bridgeHelper.registerHandler(handlerName, handler);
    }

    public void callHandler(String handlerName, String data, OnBridgeCallback callBack) {
        bridgeHelper.callHandler(handlerName, data, callBack);
    }

    // ... other delegated methods ...

    @Override
    public WebView getWebView() {
        return this;
    }
}