你的位置:首页 > Java教程

[Java教程]Webview 中 Javascript 无法调用 Java 对象


【问题产生】

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'); // 直接调用,无法找到HostAppwindow.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