標籤:efault pad 地方 import ssh play UNC 開發 更新
需求: 在原生App裡開啟webview, 嵌入H5. 在H5中點擊某個元素, 觸發與native app互動, 又跳回到app中. 同理, 在app中完成某項操作後, 獲得某個參數, 根據這個狀態重新整理頁面.
架構: Vue. JavaScript原生的寫法已經調通了, 並且與native端的已經聯調通過. 所以這裡是把它們遷移到Vue架構的寫法.
這裡要區分iOS系統和Android系統.
iOS系統
- 在這裡與iOS開發的同事協商後, 決定使用 WebViewJavascriptBridge來開發. 前端不需要放入任何js外掛程式. 只需要準備一下這段內容.
bridge.js
function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge) } if (window.WVJBCallbacks) { returnwindow.WVJBCallbacks.push(callback) } window.WVJBCallbacks = [callback] let WVJBIframe = document.createElement(‘iframe‘) WVJBIframe.style.display = ‘none‘ WVJBIframe.src = ‘https://__bridge_loaded__‘ document.documentElement.appendChild(WVJBIframe) setTimeout(() => { document.documentElement.removeChild(WVJBIframe) }, 0)}export default { callhandlerIOS(name, data, callback) { setupWebViewJavascriptBridge(function (bridge) { bridge.callHandler(name, data, callback) }) }, registerhandlerIOS(name, callback) { setupWebViewJavascriptBridge(function (bridge) { bridge.registerHandler(name, function (data, responseCallback) { callback(data, responseCallback) }) }) }}
- 在main.js裡注入
import Bridge from "./js/bridge.js";Vue.prototype.$bridge = Bridge //在這裡注入後, 頁面裡所有需要用到調用native的地方, 都可以直接調用this.$bridge.xxxnew Vue({ el: "#app", router, store, // Bridge, components: { App }, template: "<App/>",})
- 在要使用的
.vue檔案裡使用
這裡舉一個例子.
H5調用iOS
在callNative方法裡使用this.$bridge.callhandler(‘ObjC Echo‘, params, function(response){//todo})
其中ObjC Echo是和用戶端約定好的方法. 即在用戶端註冊好的方法, 寫上這個方法名, 在使用的時候用戶端就能接收到, 從而拿到params裡的參數, 而後面跟的function(response){}就是處理response裡的資料. 進行一些操作.
this.$bridge.callhandlerIOS( "HY_H5_CALL_NATIVE", { action: "pick me" }, data => { // 處理返回資料 })
iOS調用H5
使用this.$bridge.registerhandler(‘JS Echo‘, (data, responseCallback)=>{//todo}
JS Echo即是和用戶端約定好的方法名, 在用戶端使用這個方法名時, 會自動調起H5執行某些操作. 用戶端傳來的資訊放在data裡, responseCallback即執行回調.
this.$bridge.registerhandlerIOS("JS Echo", (data, responseCallback) => { alert("JS Echo called with:", data); // this.responseCallback(data)});
Android系統
由於Android系統同樣也使用webviewJavaScriptBridge, 所以我自然而然想到了是否也能像iOS一樣export出兩個處理的handler.
- 在bridge.js中添加聲明代碼
//Android 互動聲明function connectWebViewJavascriptBridgeANDROID(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge); } else { document.addEventListener( "WebViewJavascriptBridgeReady", function () { callback(WebViewJavascriptBridge); }, false ); }}
- 在bridge.js的export中添加匯出
這裡我在handler後面添加了Android作為和iOS的handler做區分.
callhandlerAndroid(name, data, callback){ //Android方法 connectWebViewJavascriptBridgeANDROID(function(bridge){ bridge.callHandler(name, data, callback) }) }, registerhandlerAndroid(name, callback){ //Android方法 connectWebViewJavascriptBridgeANDROID(function(bridge){ bridge.init(function(message, responseCallback) { if (responseCallback) { // responseCallback(data); } }); bridge.registerHandler(name, function(data, responseCallback){ callback(data, responseCallback) }) }) }
- 在
.vue檔案中使用. 使用方法同iOS
JS調用Android
this.$bridge.callhandlerAndroid( ‘action‘, {message: ‘111‘}, function(response){})
Android調用JS
this.$bridge.registerhandlerAndroid( "registerAction", (message, responseCallback) => { alert("JS Echo called with:" + message); // this.responseCallback(data) });
至此, js和Android, iOS端就算調通了.
感覺Android這一塊還有很多可以最佳化的地方, 但是我的js還掌握的不是很牢靠...所以就先這樣吧. 等以後我又新的感悟了, 再來更新.
附上所有代碼
- bridge.js代碼
//iOS 互動聲明function connectWebViewJavascriptBridgeIOS(callback) { if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge) } if (window.WVJBCallbacks) { returnwindow.WVJBCallbacks.push(callback) } window.WVJBCallbacks = [callback] let WVJBIframe = document.createElement(‘iframe‘) WVJBIframe.style.display = ‘none‘ WVJBIframe.src = ‘https://__bridge_loaded__‘ document.documentElement.appendChild(WVJBIframe) setTimeout(() => { document.documentElement.removeChild(WVJBIframe) }, 0)}//Android 互動聲明function connectWebViewJavascriptBridgeANDROID(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge); } else { document.addEventListener( "WebViewJavascriptBridgeReady", function () { callback(WebViewJavascriptBridge); }, false ); }}export default { callhandlerIOS(name, data, callback) { //iOS的方法 connectWebViewJavascriptBridgeIOS(function (bridge) { bridge.callHandler(name, data, callback) }) }, registerhandlerIOS(name, callback) { //iOS的方法 connectWebViewJavascriptBridgeIOS(function (bridge) { bridge.registerHandler(name, function (data, responseCallback) { callback(data, responseCallback) }) }) }, callhandlerAndroid(name, data, callback){ //Android方法 connectWebViewJavascriptBridgeANDROID(function(bridge){ bridge.callHandler(name, data, callback) }) }, registerhandlerAndroid(name, callback){ //Android方法 connectWebViewJavascriptBridgeANDROID(function(bridge){ bridge.init(function(message, responseCallback) { if (responseCallback) { // responseCallback(data); } }); bridge.registerHandler(name, function(data, responseCallback){ callback(data, responseCallback) }) }) }}
- main.js代碼
import Bridge from "./js/bridge.js";Vue.prototype.$bridge = Bridge/* eslint-disable no-new */new Vue({ el: "#app", router, store, components: { App }, template: "<App/>",});
.vue檔案
<template> <div> <h1>hi, this is a test</h1> <h2 v-if="isShow">234</h2> <button @click="callNative">點擊點擊</button> <h3>234</h3> </div></template><script>export default { data() { return { isShow: false }; }, created() { this.$bridge.registerhandlerIOS("JS Echo", (data, responseCallback) => { alert("JS Echo called with:", data); // this.responseCallback(data) }); this.$bridge.registerhandlerAndroid( "registerAction", (message, responseCallback) => { alert("JS Echo called with:" + message); // this.responseCallback(data) } ); }, methods: { callNative() { this.isShow = !this.isShow; if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { this.$bridge.callhandlerIOS( "HY_H5_CALL_NATIVE", { action: "pick me" }, data => { // 處理返回資料 } ) }else if (/(Android)/i.test(navigator.userAgent)){ this.$bridge.callhandlerAndroid( ‘action‘, {message: ‘111‘}, function(response){} ) } }, }};</script><style>button { margin: 30px auto; display: block; padding: 10px; border: 1px solid #ccc; background-color:dodgerblue}</style>
Vue架構下 JS與native的互動(iOS&Android)