DSbridge

  • Js communications terminal

The prompt event is captured in the WebView by the client, and the parameters are carried out to interact with the event. JSBridge source code implementation, using the SCHME protocol, is outdated.

  • The communication js

Js runtime environment, the end can inject JS objects into the JS runtime context.

Front-end – Bridge source code interpretation

var bridge = {
    default:this.// for typescript
    call: function (method, args, cb) {
        var ret = ' ';
        if (typeof args == 'function') {
            cb = args;
            args = {};
        }
        var arg={data:args===undefined?null:args}
        if (typeof cb == 'function') {
            var cbName = 'dscb' + window.dscb++;
            window[cbName] = cb;
            arg['_dscbstub'] = cbName;
        }
        arg = JSON.stringify(arg)

        //if in webview that dsBridge provided, call!
        if(window._dsbridge){
           ret=  _dsbridge.call(method, arg)
        }else if(window._dswk||navigator.userAgent.indexOf("_dsbridge")! = -1){
           ret = prompt("_dsbridge=" + method, arg);
        }

       return  JSON.parse(ret||'{}').data
    },
    register: function (name, fun, asyn) {
        var q = asyn ? window._dsaf : window._dsf
        if (!window._dsInit) {
            window._dsInit = true;
            //notify native that js apis register successfully on next event loop
            setTimeout(function () {
                bridge.call("_dsb.dsinit");
            }, 0)}if (typeof fun == "object") {
            q._obs[name] = fun;
        } else {
            q[name] = fun
        }
    },
    registerAsyn: function (name, fun) {
        this.register(name, fun, true);
    },
    hasNativeMethod: function (name, type) {
        return this.call("_dsb.hasNativeMethod", {name: name, type:type||"all"});
    },
    disableJavascriptDialogBlock: function (disable) {
        this.call("_dsb.disableJavascriptDialogBlock", {
            disable: disable ! = =false})}}; !function () {
    if (window._dsf) return;
    var ob = {
        _dsf: {
            _obs: {}},_dsaf: {
            _obs: {}},dscb: 0.dsBridge: bridge,
        close: function () {
            bridge.call("_dsb.closePage")},_handleMessageFromNative: function (info) {
            var arg = JSON.parse(info.data);
            var ret = {
                id: info.callbackId,
                complete: true
            }
            var f = this._dsf[info.method];
            var af = this._dsaf[info.method]
            var callSyn = function (f, ob) {
                ret.data = f.apply(ob, arg)
                bridge.call("_dsb.returnValue", ret)
            }
            var callAsyn = function (f, ob) {
                arg.push(function (data, complete) { ret.data = data; ret.complete = complete! = =false;
                    bridge.call("_dsb.returnValue", ret)
                })
                f.apply(ob, arg)
            }
            if (f) {
                callSyn(f, this._dsf);
            } else if (af) {
                callAsyn(af, this._dsaf);
            } else {
                //with namespace
                var name = info.method.split('. ');
                if (name.length<2) return;
                var method=name.pop();
                var namespace=name.join('. ')
                var obs = this._dsf._obs;
                var ob = obs[namespace] || {};
                var m = ob[method];
                if (m && typeof m == "function") {
                    callSyn(m, ob);
                    return;
                }
                obs = this._dsaf._obs;
                ob = obs[namespace] || {};
                m = ob[method];
                if (m && typeof m == "function") {
                    callAsyn(m, ob);
                    return; }}}}for (var attr in ob) {
        window[attr] = ob[attr]
    }
    bridge.register("_hasJavascriptMethod".function (method, tag) {
         var name = method.split('. ')
         if(name.length<2) {
           return!!!!! (_dsf[name]||_dsaf[name]) }else{
           // with namespace
           var method=name.pop()
           var namespace=name.join('. ')
           var ob=_dsf._obs[namespace]||_dsaf._obs[namespace]
           returnob&&!! ob[method] } }) }();module.exports = bridge;
Copy the code

Explain version

var bridge = {
default:
    this.// js calls Native methods
    call: function(functionName, args, callback) {
        Function (functionName,callback) function(functionName,callback)
        "function"= =typeof args && (callback = args, args = {});
        
        // Parameter object {data: args/null}
        args = { data: void 0 === args ? null : args};
        
        // If it is asynchronous and will receive the return value
        if ("function"= =typeof callback) {
            // Callback identifies the counter
            var tag = "dscb" + window.dscb++;
            // Save window[dscbX] = callback Function
            window[tag] = callback;
            // args = {data: args/null,_dscbstud:tag}
            args._dscbstub = tag
        }
        // Convert the parameter to a Json string
        args = JSON.stringify(args);
        
        var ret = "";
        // There is no place in the source where _dsbridge is injected
        if (window._dsbridge) {
            ret = _dsbridge.call(functionName, args);
        }
        
        // The client will go there, and the webView initialization will inject _DSWK =true for the window
        Low / / Android version add dsbridge tag in the lower Android version, Settings. SetUserAgentString (Settings) getUserAgentString () +" _dsbridge");
        else if (window._dswk || -1! = navigator.userAgent.indexOf("_dsbridge")) {
            ret = prompt("_dsbridge=" + functionName, args);
        }
        return JSON.parse(ret || "{}").data
    },
    
    // javascript registers a method to be called by Native; if callback is passed in, it is an asynchronous method
    register: function(jsFunctionName, receiveParamsFunction, callback) {
        
        Callback = {_obs:{}};
        callback = callback ? window._dsaf : window._dsf;
        
        // Only once, in order to call the native dsinit method once
        window._dsInit || (window._dsInit = !0.setTimeout(function() {
            bridge.call("_dsb.dsinit")},0));
        
        Callback = {jsFunctionName: receiveParamsFunction:, _obs:{}};
        "object"= =typeof receiveParamsFunction ? callback._obs[jsFunctionName] = receiveParamsFunction : callback[jsFunctionName] = receiveParamsFunction
    },
    
    // js registers asynchronous methods for Native calls
    registerAsyn: function(b, a) {
        this.register(b, a, !0)},// Is there a Native method
    hasNativeMethod: function(b, a) {
        return this.call("_dsb.hasNativeMethod", {
            name: b,
            type: a || "all"})},/ / disable the Dialog
    disableJavascriptDialogBlock: function(b) {
        this.call("_dsb.disableJavascriptDialogBlock", {
            disable:!1! == b }) } };// https://www.cnblogs.com/binbin001/p/11393040.html
// Execute a piece of code immediately. The function expression followed by '()' can be executed immediately
// function(){}()
(function(){
    
    // add attributes dynamically to the js object
    // obj[property] = xxx. not obj.property = xxx
    
    // 1. Return if the Window has an '_dsf' attribute added
    if(window._dsf) return;

    // 2. Window adds an '_dsf' object property to save the synchronization method
    window["_dsf"] = { _obs:{} };
    // 3. Window adds a '_dsaf' object property to save the asynchronous method
    window["_dsaf"] = { _obs:{} };
    // 4. Window adds a callback count unique identifier
    window["dscb"] = 0;
    // 5. Window adds a bridge attribute
    window["dsBridge"] =  bridge;
     //6. Window adds an interface closure method
    window["close"] = function(){
        bridge.call("_dsb.closePage");
    };
    // 7.window adds a function that handles Native methods uniformly
    //a = { "callbackId":id, "method":name, "data":[x,y,z,..] }
    window["_handleMessageFromNative"] = function(a){
        // An array of parameters to call the method
        var e = JSON.parse(a.data),
        
        // Temporary objects
        b = {
            id: a.callbackId,
            complete:!0
        },
        // Synchronize methods
        c = this._dsf[a.method],
        // Asynchronous method
        d = this._dsaf[a.method],
        
        
        h = function (a, c){
           b.data = a.apply(c, e);
           bridge.call("_dsb.returnValue", b);
        },

        k = function (a, c){
            e.push(function (a, c){
                b.data = a;
                b.complete = !1! == c; bridge.call("_dsb.returnValue", b)
            });
            a.apply(c, e);
        };

        if(c) h(c, this._dsf);
        else if(d) k(d, this._dsaf);
        else if(c = a.method.split("."), !(2 > c.length)){
            a = c.pop();
            var c = c.join("."),
                d = this._dsf._obs,
                d = d[c] ||
                {},
                f = d[a];
            f && "function"= =typeof f ? h(f, d) : (d = this._dsaf._obs, d = d[c] ||
            {}, (f = d[a]) && "function"= =typeof f && k(f, d))
        }
    };
    
    bridge.register("_hasJavascriptMethod".function(a, b) {
        b = a.split(".");
        if (2 > b.length) return! (! _dsf[b] && ! _dsaf[b]); a = b.pop(); b = b.join(".");
        return(b = _dsf._obs[b] || _dsaf._obs[b]) && !! b[a] }); }) ();Copy the code

The advantages and disadvantages

advantages

  • The three-terminal interaction is compatible

disadvantages

  • Prompt events occupy, although handled, there is still a risk