應(yīng)用場(chǎng)景:
在Flutter 中顯示一個(gè)網(wǎng)頁(yè)(H5之類)提完,然后在Flutter中可以調(diào)用網(wǎng)頁(yè)js里的方法百新; js里也可以調(diào)用 Flutter
中的方法珊燎。這樣就可以相互通信檬贰,方便一些功能的實(shí)現(xiàn)姑廉。
在Flutter中顯示一個(gè)網(wǎng)頁(yè)一般我們借助于官方提供的 webview_flutter 這個(gè)插件。
要想Flutter與js相互通信也是要借助于這個(gè)插件中的 JavascriptChannel翁涤。 我們也知道Flutter 在和android通信的時(shí)候是借助于MethodChannel桥言,這兩個(gè)蠻像的萌踱。
在說(shuō)具體的調(diào)用方法之前先說(shuō)一下WebView中幾個(gè)關(guān)鍵的方法
1)onWebViewCreated 這個(gè)方法在webView 創(chuàng)建完成時(shí)調(diào)用,只會(huì)被調(diào)用一次 号阿,返回的參數(shù)是WebViewController 并鸵。 后面我們Flutter調(diào)用js方法的時(shí)候就會(huì)用到這個(gè) WebViewController。
2)onPageFinished 這個(gè)方法在頁(yè)面加載完成時(shí)調(diào)用扔涧, 在里邊可以通過 WebViewController 來(lái)調(diào)用 js
調(diào)用方式 : _webViewController.evaluateJavascript("js 方法名").then((res){
// 這個(gè)res 是js方法的返回值
});
- Flutter中調(diào)用Js里定義的方法 (Flutter 調(diào) js )
// 這個(gè)showMessage 是在js中定義的方法园担,這個(gè)方法的返回值是true
// _controller就是WebViewController
_controller?.evaluateJavascript("showMessage('This message is from Flutter!')").then ((res) {
print ("evaluateJavascript-res: ${res}"); // evaluateJavascript-res: true
});
- Js 中發(fā)消息給Flutter(js調(diào)Flutter )
// 下面這段代碼是js中的一個(gè)方法
function sendMessage (message ) {
// 這個(gè)MessageDeal是和Flutter里JavascriptChannel中的name一致的。
// 不用自己確切的定義枯夜,只要Flutter和js里保持一樣就可以
// 這里我最開始看這個(gè)的時(shí)候一直沒搞懂MessageDeal是什么弯汰,后來(lái)敲了一遍代碼終于明白了,
// 這個(gè)其實(shí)和MethodChannle中的channel字符串有類似的意思湖雹,唯一標(biāo)識(shí)
MessageDeal.postMessage(message); // 關(guān)鍵
document.getElementById ("content2").innerHTML = message;
}
完整的代碼 :
js端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>html demo</title>
</head>
<body>
<script>
<!-- 這個(gè)方法是用來(lái)給Flutter調(diào)用的(即:Flutter調(diào)用js方法)-->
function showMessage (message){
document.getElementById ("content").innerHTML = message;
return true;
}
<!-- 這個(gè)方法是用來(lái)發(fā)送一個(gè)消息給Flutter的(即:js調(diào)用Flutter方法)-->
function sendMessage (message ) {
MessageDeal.postMessage(message);
document.getElementById ("content2").innerHTML = message;
}
</script>
<div id="content"><span>Flutter發(fā)送過來(lái)的消息是: </span>test</div>
<div id="content2"><span>我發(fā)送給Flutter的消息是:</span>test2</div>
<button onclick="sendMessage('我來(lái)自js調(diào)用sendMessage蝙泼,我調(diào)用了Flutter中的功能')">send a message to Flutter</button>
</body>
</html>
Flutter端:
在本地測(cè)試的時(shí)候, 可以用上邊的Html文件劝枣,然后用http-server在html文件所在目錄開啟一個(gè)本地的服務(wù),這樣就可以通過http://你的ip:8080/demo.html來(lái)訪問你的html文件來(lái)測(cè)試了织鲸。 沒有http-server這個(gè)的可以去安裝一下舔腾,用這個(gè)還是還方便的。 【安裝http-server: npm i http-server -g 】
WebView(
key: key,
javascriptMode: JavascriptMode.unrestricted,
initialUrl: url, // 網(wǎng)頁(yè)地址: "http://172.18.230.138:8080/demo.html";
onWebViewCreated: (controller) {
_controller = controller;
},
navigationDelegate: (NavigationRequest request) {
var url = request.url;
setState(() {
isLoading = true; // 開始訪問頁(yè)面搂擦,更新狀態(tài)
});
return NavigationDecision.navigate;
},
onPageFinished: (url) {
_controller?.evaluateJavascript("showMessage('This message is from Flutter!')").then ((res) {
print ("evaluateJavascript-res: ${res}");
});
},
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: "MessageDeal",
onMessageReceived: (JavascriptMessage message) {
// 這里接收到的就是 js 中發(fā)送過來(lái)的message稳诚。 和js里MessageDeal.postMessage(message) 中的message 對(duì)應(yīng) 。
// 可以根據(jù)message來(lái)做一些相應(yīng)的處理
print("${message.toString()}, ${message.hashCode}, message: ${message.message}") ;
// 收到消息后回復(fù)一個(gè)消息給js那邊
_controller?.evaluateJavascript("showMessage ('我(Flutter)收到了你的消息[${message.message}].)");
}),
].toSet(),
)
如上瀑踢, 簡(jiǎn)單的js發(fā)消息給flutter , flutter調(diào)js方法就說(shuō)完了 扳还。 僅記錄學(xué)習(xí)。