了解Android Webview JavaScript接口

8

我创建了一个Android WebView,并使用addJavascriptInterface(mObject,“jsinterface”)注入了javascript接口。它一直很正常,直到我使用new运算符在JavaScript中创建了同名(jsinterface)的对象。

我的Java代码:

WebView mWebView = findViewById(R.id.myWebView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new MyWebChromeClient((Activity)mContext));
mWebView.addJavascriptInterface(new testClass(), "jsinterface");
mWebView.loadUrl("UrlToLoad");

testClass.java

public class testClass{
    public testClass() {
    }

    @JavascriptInterface
    public String testNativeMethod() {
        return "Java method called!!";
    }
}

我的JavaScript代码

test.js

function test(msg){
    this.message = msg;

    this.testJSMethod = function(){
        return this.message;
    }
}

alert(jsinterface.testNativeMethod()); // prints Java method called!!
jsinterface= new test("JS method called...");
alert(jsinterface.testJSMethod()); // prints JS method called...
alert(jsinterface.testNativeMethod()); // errors "NPMethod called on non- NPObject"

问题:

一个javascript对象能否同时访问JavaScript方法和通过javascriptinterface公开给它的本地JAVA方法?有没有可能设置webview的任何属性或执行任何JS script来完成这个任务?

2个回答

12

在JavaScript中思考 document。当您在Web浏览器中时,这是一个全局对象,您可以在任何时候访问它。如果您创建自己的new变量名为document,则无法访问全局document

当您执行此行时:

    mWebView.addJavascriptInterface(new testClass(), "jsinterface");

您正在添加一个名为jsinterface的全局对象。这与document的情况相同。如果您创建一个同名的变量,它将覆盖现有的全局引用。

一旦将Javascript接口添加到WebView中,您无需创建对该接口的new引用。 addJavascriptInterface已经为您完成了这项工作。


5

尝试

您可以尝试创建另一个对象,用于重新翻译对JavaScript接口的调用。在WebViewClient中实现onPageStarted方法,并在onPageStarted方法中注入JavaScript,具体方法如下。

 mWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
        @Override
        public void onPageStarted (WebView view, String url, Bitmap favicon){
            String jsScript= "javascript:var functions_array = ['testNativeMethod'];";
                   jsScript+="var jsinterface = {};"
                   jsScript+="functions_array.map(function(id){"
                   jsScript+="jsinterface[id]= function() {"
                   jsScript+="try{return temp_obj[id].apply(temp_obj, arguments);}"
                   jsScript+="catch(e) { console.log('ERROR: ' + e + ', method ' + id);"
                   jsScript+="return false;}}})"
            view.loadUrl(jsScript);
        }
    });

希望这有所帮助 :-)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接