H5与原生交互

前言 提到混合式开发的童鞋,是不是想到是指 React Native , Weex,或者流行的 Flutter, 有意观赏上类分享,那友情提醒误入文章的你,打开控制台输入 history.go(-1)。 本篇总结的混合式开发,指 原生App 与 H5 的互相传递参数或交互逻辑,场景就是H5嵌套于原生中,通过原生访问H5页面。 至于原生APP为什么采用H5,想必大家可能想到一个原因是,原生APP审核需要一定时间,营销推广活动比较频繁的公司,所以会选择H5开发。 本篇主要带领大家,熟悉了解 H5与原生交互 需求中,H5部门与原生部门这块相关协调工作,让大家有彼此工作大致了解。欢迎提补充建议或是错误指正。 安卓、H5之间传参交互 安卓 与 H5前端 协调工作较为简单,只需要安卓将交互方法注册到window的对象名,提供给H5。然后就是两边的自我代码开发。 安卓方面工作 搭建安卓与H5交互通道,定义提供原生通道名,并项目启动时调用。 书写安卓、H5,相互传参的方法 与H5联调方法,是否正常实现传参或功能逻辑 下面代码片段,通道名设置为 Flight, 交互方法在 Flight类实现 @SuppressLint("JavascriptInterface") private void initWebViewCallBack() { Log.e(TAG, "initWebViewCallBack: "); if (flightWv != null) { flightWv.addJavascriptInterface(new Flight(), "Flight"); } } public class Flight { @JavascriptInterface public String getVersion() { H5Besn bean = new H5Besn(); bean.setCity(Cfg.localityCityName); bean.setLat(Cfg.myLatitude); bean.setLon(Cfg.myLongitude); bean.setVersionName(AppUtils.getVersionName(FlightWebAcitvity.this)); String json = GsonUtils.createJsonStr(bean); return json; } } H5前端工作 在项目入口文件引入,与原生交互代码。当然考虑到与原生操作过多,避免入口文件臃肿,可在入口文件引入专门原生操作的分流的文件命名为 bride.js。 在 bridge.js 区分 IOS,安卓环境,或者其他环境等,便于安卓方法只注册在安卓设备下,避免冗余无用代码 安卓方法调用 下面前端代码相关片段: import store from '@/store' import { setupWebViewJavascriptBridge } from '@/utils' // ... // 判断环境,以下添加了 && u.indexOf('matafyApp') 此类并唯一标识哪个APP标识(找原生开发同学寻要) const urlParams = urlParamsObj() const u = navigator.userAgent const isAndroid = (u.indexOf('Android') > -1 || u.indexOf('Adr') > -1) && u.indexOf('matafyApp') > -1 // Android终端且在原生app内 const isiOS = u.indexOf('iPhone') > -1 && u.indexOf('matafyApp') > -1 // iOS终端且在原生app内 !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) const isMobile = !!u.match(/AppleWebKit.*Mobile.*/) // 是否为移动终端 const isMiniprogram = urlParams['weixinId'] // 微信7.0.0开始,允许userAgent来判断小程序环境,兼容为携带weixinid的路径 // ...... // 判断处于哪个环境下,并存于vuex的store中,不过如果你项目未使用vuex,大可不必使用。 if (isMobile) { if (isAndroid) { store.dispatch('app/setDevice', 'android') } else if (isiOS) { store.dispatch('app/setDevice', 'ios') } else if (isMiniprogram || window.__wxjs_environment === 'miniprogram') { if (isMiniprogram) sessionStorage.setItem('weixinId', isMiniprogram) store.dispatch('app/setDevice', 'wx_program') } else { store.dispatch('app/setDevice', 'mobile') } } else { store.dispatch('app/setDevice', 'mobile') } // 原生交互方法 switch (store.getters.device) { case 'android': // 获取token const setToken = (token) => { store.dispatch('app/setToken', token) } // 获取版本号信息 const setVersion = (version) => { localStorage.setItem('sendVersion', version) } window.setVersion = setVersion // 注意:调用方法,定要注册在window对象下 window.setToken = setToken break; // ... } IOS、H5之间传参交互 IOS 与 H5,不需要像安卓提前告知暴露的对象名。 IOS方面工作 安装与H5交互的通道 pod 'WebViewJavascriptBridge', '~> 6.0' 以下IOS代码用法: 也可参考github代码,点击链接 Import the header file and declare an ivar property: #import "WebViewJavascriptBridge.h" Instantiate WebViewJavascriptBridge with a WKWebView, UIWebView (iOS) or WebView (OSX): self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView]; Register a handler in ObjC, and call a JS handler: [self.bridge registerHandler:@"ObjC Echo" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"ObjC Echo called with: %@", data); responseCallback(data); }]; [self.bridge callHandler:@"JS Echo" data:nil responseCallback:^(id responseData) { NSLog(@"ObjC received response: %@", responseData); }]; H5前端工作 前端工作也只有短短两步,第一步,就是将连接webview通道的方法,可存放于函数的文件,便于多么模块调用。第二步,调用通道方法,进行注册原生需要调用方法或主动调用原生方法。 函数库文件 src/utils/index.js 文件部分代码如下: /** * @export ios与js建立连接基础方法 * @param {Function} 调用方法的回调 */ export function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge) } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback) } window.WVJBCallbacks = [callback] var WVJBIframe = document.createElement('iframe') WVJBIframe.style.display = 'none' WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__' document.documentElement.appendChild(WVJBIframe) setTimeout(() => { document.documentElement.removeChild(WVJBIframe) }, 0) } 项目处理原生文件 src/utils/bridge.js,需项目入口文件引入,部分代码如下: import store from '@/store' import { setupWebViewJavascriptBridge } from '@/utils' // ... switch (store.getters.device) { // ... case 'ios': setupWebViewJavascriptBridge((app) => { app.registerHandler('sendToken', (token, responseCallback) => { // 获取IOS原生APP传递过来的token,存于前端数据池(仓库) store.dispatch('app/setToken', token) }) } break; // ... } 常见的H5与原生交互的应用场景 原生与H5交互传参的应用场景,情况分为两类。第一,原生传递H5参数或回调相关操作;第二,H5主动获取原生参数或进行回调相关操作。 各个公司各个项目需求不一致,例如,token传递,经纬度传递,APP版本信息传递,app设备Id的传递,设置原生系统栏的背景色字号色的传递,调用原生方法打开第三方浏览器或者内置浏览器的方法,h5控制原生返回键的逻辑等等 春雨如酒.jpg

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):