How to Decouple Hybrid H5 for True Cross‑Platform Compatibility

This article explains the concepts of Hybrid H5, its inherent coupling with native apps, and provides a step‑by‑step guide on decoupling through jsapi layers to restore cross‑platform functionality across multiple apps and platforms, illustrated with code examples and diagrams.

Tencent TDS Service
Tencent TDS Service
Tencent TDS Service
How to Decouple Hybrid H5 for True Cross‑Platform Compatibility

Cross‑platform capability is one of the most important features of H5, but Hybrid H5 often loses this ability because it heavily depends on a specific app. By decoupling the strong dependency, the cross‑platform nature of H5 can be restored. The author shares insights gained while developing the HandQQ Red Packet Reward project, which required multi‑app cross‑platform compatibility.

Hybrid H5 Cross‑Platform

Before diving in, two terms are defined:

Hybrid H5 mixes native capabilities with web pages, allowing calls to native APIs and thus tightly coupling with the host app. WeChat and HandQQ H5 pages are typical examples.

Cross‑platform means an H5 page can run on multiple platforms simultaneously; the more platforms supported, the stronger the cross‑platform capability.

Because Hybrid H5 relies on a specific app, it usually lacks cross‑platform support. This article explores how to restore it by decoupling the communication between Hybrid H5 and native.

Communication Principles Between Hybrid H5 and Native

Key points:

One communication medium: a custom native protocol.

Three communication actions: trigger, invoke, callback.

1. Communication medium – native protocol

The protocol resembles an HTTP‑like format:

protocol://path?param1=XXX&param2=XXX&param3=XXX#callback

Components:

protocol: app‑defined scheme (e.g., jsbridge://).

path: native capability identifier.

parameters and callback identifier.

Example: jsbridge://method?a=2&b=3#h5MethodTag 2. Trigger

H5 actions that native can capture, such as location.href='jsbridge://method?a=2&b=3#h5MethodTag', cause the native side to receive the protocol string.

3. Invoke

Native parses the protocol and routes to the corresponding method. Example for iOS (Swift):

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    let url = request.URL
    let scheme = url?.scheme
    let method = url?.host
    let query = url?.query
    if scheme == "jsbridge" {
        switch method! {
        case "method": self.method()
        case "openTenpayView": self.openTenpayView()
        default: break
        }
        return false
    }
    return true
}

4. Callback

After native finishes processing, it calls back the H5 JavaScript function:

webview.stringByEvaluatingJavaScriptFromString("H5MethodTag(data)")

First Decoupling: In‑App Cross‑Platform via jsapi

Directly using the native protocol couples H5 to the current platform. To achieve in‑app cross‑platform support, apps expose a jsapi that abstracts protocol differences. The jsapi provides a unified function interface for H5.

Example jsapi definition:

ns.method({/* cfg */}, function(data) {/* callback */})

Core steps of the jsapi:

API creation – encapsulate platform differences.

Protocol URL assembly – build the pseudo‑protocol string.

Iframe creation – send the request without affecting the H5 flow.

API creation example (HandQQ):

mqq.build('mqq.tenpay.openTenpayView', {
    iOS: function(options, callback) {
        var callbackName = callback ? mqq.callback(callback) : null;
        mqq.invokeClient('pay', 'openTenpayView', {'params': options, 'callback': callbackName});
    },
    android: function(params, callback) {
        mqq.invokeClient('pay', 'openTenpayView', JSON.stringify(params), callback);
    },
    supportInvoke: true,
    support: {iOS: '4.6.1', android: '4.6.1'}
});

Calling the API from H5:

mqq.tenpay.openTenpayView({/* data */}, function(ret) {/* callback */});

Protocol URL assembly (simplified):

sn = storeCallback(callback);
url = 'jsbridge://' + encodeURIComponent(ns) + '/' + encodeURIComponent(method);
argus.forEach(function(a, i) {
    if (exports.isObject(a)) a = JSON.stringify(a);
    url += (i === 0 ? '?p=' : '&p' + i + '=') + encodeURIComponent(String(a));
});
url += '#' + sn;
result = openURL(url, ns, method);

Iframe request:

var iframe = document.createElement('iframe');
iframe.style.cssText = 'display:none;width:0;height:0';
iframe.onload = failCallback;
iframe.src = url;
(document.body || document.documentElement).appendChild(iframe);
setTimeout(function(){ iframe && iframe.parentNode && iframe.parentNode.removeChild(iframe); }, 0);

Second Decoupling: Cross‑App via H5‑Level jsapi

When a Hybrid H5 must run on multiple apps (e.g., both HandQQ and Qzone), a second layer of jsapi is introduced on the H5 side to abstract differences between app‑level jsapis.

Core actions of the H5 jsapi:

App‑jsapi difference request – load the appropriate app jsapi based on the runtime environment.

App‑jsapi difference encapsulation – provide a unified interface that maps to the underlying app’s native calls.

Environment detection and app‑jsapi loading example:

(function(){
    var ua = navigator.userAgent || "",
        isQQ = ua.match(/QQ\/([\d\.]+)/),
        isQzone = ua.match("Qzone");
    if (isQQ) {
        document.write("<script src='https://open.mobile.qq.com/sdk/qqapi.js?_bid=152'><\/script>");
    } else if (isQzone) {
        document.write("<script src='https://qzonestyle.gtimg.cn/qzone/phone/m/v4/widget/mobile/jsbridge.js'><\/script>");
    } else {
        var currentHref = window.location.href;
        window.location.href = 'mqqapi://forward/url?url_prefix=' + btoa(currentHref) + '&version=1&src_type=web';
        setTimeout(function(){
            if (confirm('请在手机QQ中使用~')) {
                window.location.href = 'mqqapi://forward/url?url_prefix=' + btoa(currentHref) + '&version=1&src_type=web';
            }
        }, 0);
    }
})();

Encapsulation example for opening a native Tenpay view:

var mod = {
    openTenpayView: function(param, callback) {
        if (isQQ) {
            var param = $.extend({userId: $.getCookie('uin').replace(/^o0*/, '')}, param);
            mqq.tenpay.openTenpayView(param, callback);
        } else {
            var targetHref = 'http://testhost.com/jump.html?go=' + param.viewTag + '&_wv=' + (1+2+1024+2097152+33554432);
            window.location.href = 'mqqapi://forward/url?url_prefix=' + btoa(targetHref) + '&version=1&src_type=web';
        }
    },
    openUrl: function(paramObj) {
        if (isQQ) {
            mqq.ui.openUrl({url: paramObj.url, target: 1});
        } else if (isQzone) {
            mqq.invoke("ui", "openUrl", {url: paramObj.url, target: 1, style: 1});
        } else {
            location.href = paramObj.url;
        }
    }
};

Conclusion

H5 is inherently cross‑platform, but Hybrid H5 loses this advantage due to tight coupling with native code. Restoring cross‑platform capability requires decoupling the native dependencies through layered jsapi abstractions, both within a single app and across multiple apps.

Decoupling is a crucial skill for developers; applying it to Hybrid H5 demonstrates how to regain lost capabilities and can lead to surprising benefits in other scenarios as well.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendnative bridgeHybrid H5JSAPI
Tencent TDS Service
Written by

Tencent TDS Service

TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.

0 followers
Reader feedback

How this landed with the community

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.