zoukankan      html  css  js  c++  java
  • H5嵌入APP后,原生APP与H5之间交互

    原生APP跳转到H5页面时,往往需要携带一些用户信息,之前做法是在跳转的地址中拼接H5页面需要的参数,现在通过window.WebViewJavascriptBridge悄悄的进行数据交互。

    本文主要从H5的角度记录交互思路:

    1:安卓环境和ios环境稍微有点不同,需要根据navigator.userAgent判断一下当前环境

    2:仍然是APP环境不同,安卓需要进行兼容性判断,如果不存在window.WebViewJavascriptBridge变量,需要手动添加Dom的WebViewJavascriptBridgeReady事件监听;ios同样需要判断是否存在window.WebViewJavascriptBridge变量,如果不存在继续判断window.WVJBCallbacks变量,如果仍然不存在,则手动赋值为H5回调,然后document.createElement('iframe')插入document中,随即移除。

    3:以上处理完成后,通过WebViewJavascriptBridge变量来注册【事件】以便APP能监听到并执行相应操作

    4:3中需要对安卓系统进行init处理,如果是安卓系统,注册事件之前需要先调用WebViewJavascriptBridge.init()

    方法(注意: 一个页面整个生命周期过程中,只能进行一次init()否则会报错,我的做法是通过一个全局变量来判断是否初始化过)

    以下是具体代码:

    //针对安卓和ios系统,对window.WebViewJavascriptBridge进行兼容性处理
    function setupWebViewJavascriptBridge(callback) {
    	var u = navigator.userAgent;
    	var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
    	var isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
    	if (isAndroid) {
    		if (window.WebViewJavascriptBridge) {
    			callback(WebViewJavascriptBridge)
    		} else {
                //添加dom事件
    			document.addEventListener(
    				'WebViewJavascriptBridgeReady',
    				function () {
    					callback(WebViewJavascriptBridge)
    				},
    				false
    			);
    		}
    			
    	}
    	if (isiOS) {
    		console.log('isiOS')
    		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__';
    		document.documentElement.appendChild(WVJBIframe);
    		setTimeout(function () {
    			document.documentElement.removeChild(WVJBIframe)
    		}, 0)
    	}
    }
    
    //封装方法,key:跟原生定义好的要捕获的名称, callback:原生捕获后执行的回调,此处可以写H5的后续执行方法,params:对象,要传给原生的参数
    var setupWebViewBridge = function (key, callback, params) {
    	setupWebViewJavascriptBridge(function (bridge) {
    		var u = navigator.userAgent;
    		var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
    		var isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
            //自己定义的全局变量,用来判断当前页面中安卓系统是否进行过一次初始化,页面卸载时取消赋值
    		if (!window.hadCalledWindow_WebViewJavascriptBridge ) {
    			if (isAndroid) {
    				window.hadCalledWindow_WebViewJavascriptBridge = true 
    				bridge.init(function (message, responseCallback) {
    					console.log('JS got a message', message);
    					var data = {
    						'Javascript Responds': '测试中文!'
    					};
     
    					if (responseCallback) {
    						console.log('JS responding with', data);
    						responseCallback(data);
    					}
    				});
    			}
    		}
    		bridge.callHandler(
    			key,
                //安卓系统必须传一个参数,否则捕获不到,因此,默认传入一个_x_变量 
    			JSON.stringify({
    				...params,
    				_x_: 1,
    			}),
    			callback
    		);
     
    	})
    }
    

    原生APP里,注册要捕获的方法:

    bridge.registerHandler('jsbridge_showMessage', function (data, responseCallback) {
                 showResponse(data);
             });
    

    转载来源于 https://blog.csdn.net/haoyanyu_/article/details/89237819

    移动端混合开发,需要原生与h5交互。
    目前接触过的两种方法:

    1. 大多数是直接通过webview代理,理解的是通过拦截调用与原生进行交互。任意版本都支持。
    2. 使用第三方库WebViewJavaScriptBridge。
      这里主要整理下WebViewJavaScriptBridge在前端部分的使用:
      【用于 WKWebView & UIWebView 中 OC 和 JS 交互(ios)】

    注册监听事件(固定代码):

    /*这段代码是固定的,必须要放到js中*/
    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__';
    	document.documentElement.appendChild(WVJBIframe);
    	setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
    

    js与原生方法调用部分

    //添加原生调起js方法
    setupWebViewJavascriptBridge(function(bridge) {
         /* Initialize your app here */
         //所有与iOS交互的JS代码放这里!
    
        //js注册方法让原生调起(原生调用js)
        
        //name: 和原生约定的调用方法名
        //function(data,callback):调用方法的具体内容,data为原生传过来的参数,callback为js给原生的回调函数             
        bridge.registerHandler("jsFunction",function(data,responseCallback){
            alert("do sth with"+data)
            responseCallback("js calls back to oc");
        });
        
        
        //js唤起原生注册的方法(js调用原生)
        
        //name: 和原生约定的调用方法名
        //data: 向原生传递的参数
        //function: 原生调用后的回调函数(回调结果处理)
        bridge.callHandler('ocFunction',data,function(res){
             alert("js has received the result:"+res);
        });
    }
    

    备注:

  • 相关阅读:
    计算机组成原理实验总结
    Matlab图像匹配问题
    局域网实验
    信号量与共享存储区(操作系统实验三)
    路由器配置及IP设置及ping命令使用
    自我介绍是一门学问
    数据库管理系统的维护与管理
    高数讲课教后感
    node Unexpected token import(node 目前默认不支持es6 的模块 import解决方法有2)
    Cookie/Session机制详解
  • 原文地址:https://www.cnblogs.com/liliuyu/p/13830756.html
Copyright © 2011-2022 走看看