【問題產生】 Webview 通過 addjavascriptInterface 傳遞對象給前端,一切正常。但是 Android官方已提醒此功能是有安全風險,改用 safe-java-js-webview-bridge 做java和js交互。 官方的用法正常: 但如果我們在body里的<script ...
【問題產生】
Webview 通過 addjavascriptInterface 傳遞對象給前端,一切正常。但是 Android官方已提醒此功能是有安全風險,改用 safe-java-js-webview-bridge 做java和js交互。
官方的用法正常:
<ul class="entry"> <li onclick="HostApp.alert('HostApp.alert');">HostApp.alert</li> <li onclick="HostApp.toast('HostApp.toast');">HostApp.toast</li> </ul>
但如果我們在body里的<script>標簽這樣寫,就無法獲取HostApp對象:
HostApp.alert('alert'); // 直接調用,無法找到HostApp window.onload = function(){ HostApp.toast('document ready now'); // onload後調用,依然無法找到HostApp };
$(document).ready(function(){ HostApp.toast('document ready now'); // ready後調用,依然無法找到HostApp });
【原因】
Safe Java-JS WebView Bridge 註入HostApp-JS片段的時機,可能在onload前也可能在其後。
如果document.ready的時候HostApp JS已經註入成功,在onload的時候調用沒有問題。當onload的時候HostApp JS還未開始註入,就無法找到HostApp了。
【解決】
官方提供方法:
在js腳本層就需要做出變動,即輪詢狀態,直到端註入成功或者超時(1.5s),再發生回調。具體實現如下(下麵的是以 zepto.js的$.ready()函數改造為例)。
//針對DOM的一些操作 // Define methods that will be available on all // Zepto collections $.fn = { //DOM Ready ready: function(callback, jumpHostAppInject) { var originCb = callback; var mcounter = 0; //嘗試等待(1500ms超時)讓端註入HostApp Js callback = function () { if(!window.HostApp && mcounter++ < 150)setTimeout(callback, 10);else originCb($); }; //是否跳過等待HostApp的註入 if (jumpHostAppInject) { callback = originCb; } if (readyRE.test(document.readyState)) callback($); else document.addEventListener('DOMContentLoaded', function() { callback($) }, false); return this }, ... ... };
這樣的機制也就解釋了為什麼不把Java層的JS註入放在OnPageFinish了,如果那樣頁面輪詢的次數就會上升,等待的時間就會變長,而且有可能會超時。好了,有了上面的改動,頁面初始載入完備時需要立即觸發HostApp的調用,如下:
$(function () { HostApp.alert("HostApp ready now"); });
如果懶得去修改,可以到 gitHub 下載此插件提供的 zepto.js
由於本人項目沒有用zepto,在初始化init的時候,按官方推薦的方法做了一個輪詢。
var step = 0; // 重試次數 window.onload = function () { function isReady() { if(step < 150 && !window.HostApp) { // 重試150次 step ++; setTimeout(isReady,10); } else { init(); } } isReady(); };
更多使用說明及完整源代碼見:Safe Java-JS Bridge In Android WebView[Github]
參考:http://mobile.51cto.com/aprogram-452011.htm