項目中用到了webview_flutter這個插件肴楷,它允許我們在Flutter里面嵌套WebView辖众,同時我們也可以利用
addJavaScriptChannel方法來讓H5和我們交互闺兢。
但現(xiàn)在有一個問題就是赌蔑,addJavaScriptChannel可以讓h5單向給flutter發(fā)消息莫换,但如何在收到消息后回調(diào)h5呢乌奇?
我們可以利用runJavaScriptReturningResult方法來調(diào)用h5里面js的方法驶鹉,
例如
controller.runJavaScriptReturningResult(
"window.JSBridgeCallback($id, '${json.encode(result)}')");
這段代碼的的意思就是執(zhí)行js中的
window.JSBridgeCallback = JSBridgeCallback;
const JSBridgeMap = {};
let callID = 0;
function JSBridgeCallback(id, params) {
console.log("JSBridgeCallback", id, params);
JSBridgeMap[id](params);
JSBridgeMap[id] = null;
delete JSBridgeMap[id];
}
方法。
接下來是具體步驟
- 在flutter里面,調(diào)用addJavaScriptChannel方法來在js的window對象上掛載一個對象
addJavaScriptChannel("Flutter", onMessageReceived: (message) {
print("Flutter received: ${message.message}");
final jsonObject = json.decode(message.message);
final id = jsonObject['callID'];
const result = {"version": 10};
controller.runJavaScriptReturningResult(
"window.JSBridgeCallback($id, '${json.encode(result)}')");
})
我們需要h5告訴我們回調(diào)id子寓、方法名稱和參數(shù)
- 在H5項目中新建一個js文件暗挑,添加如下內(nèi)容
export function callFlutter(name, params, callback) {
if (window.Flutter) {
const id = callID++;
const paramsObj = {
method: name,
callID: id,
data: params || null
}
JSBridgeMap[id] = callback || ((result) => {
});
// JSBridgeHandle.call(method, JSON.stringify(paramsObj));
window.Flutter.postMessage(JSON.stringify(paramsObj));
}
}
window.JSBridgeCallback = JSBridgeCallback;
const JSBridgeMap = {};
let callID = 0;
function JSBridgeCallback(id, params) {
console.log("JSBridgeCallback", id, params);
JSBridgeMap[id](params);
JSBridgeMap[id] = null;
delete JSBridgeMap[id];
}
我們聲明一個JSBridgeCallback方法,并把它掛載到window上斜友,叫什么名字看你的喜好炸裆,不一定非要這個名字。
暴露callFlutter給外面調(diào)用鲜屏,callFlutter代碼的大致意思是
把回調(diào)函數(shù)保存到JSBridgeMap里面烹看,然后把方法id、參數(shù)和方法名稱打包成一個json通過window.Flutter.postMessage傳給flutter洛史。
- 在H5的一個按鈕上調(diào)用callFlutter方法惯殊,給flutter傳遞參數(shù)并拿到flutter的回調(diào),我這里用的框架是React
function App() {
const [text, setText] = React.useState('Hello, Flutter!');
return (
<div className="App">
<h1>{text}</h1>
<button onClick={() => {
callFlutter('getAppVersion', {method: 'showToast', args: ['Hello, Flutter!']}, (result: any) => {
// console.log("收到了來自Flutter的回調(diào): " + result);
setText(result);
});
}}>點我
</button>
</div>
);
}
測試
我們在flutter里面的h5頁面點擊按鈕也殖,拿到了flutter傳來的結(jié)果并顯示
Screenshot_20231112-211205.png