最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - JavaScript Interface Cannot Find Function - Stack Overflow

programmeradmin1浏览0评论

I have a JavaScriptInterface class that has a single function. The function is annotated with @JavascriptInterface and I believe I have set it up correctly.

public class JavaScriptInterface {

    ...

    @JavascriptInterface
    public void processBody(String uri, String body) {
        Log.d(TAG, "Process body");
        ...
    }
}

Then I set JavaScriptEnabled on the WebView and attempt to call the function:

final WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptInterface(), "java");

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        Log.d(TAG, "Page finished");
        callJavaScript();
    }
});

The page finishes loading, then I have tried a variety of methods to call the JavaScript function from my JavaScriptInterface. Using one of these two methods:

view.evaluateJavascript(javascript);

view.loadUrl("javascript:" + javascript);

And one of these javascript strings:

"(function() { window.java.processBody('" + url + "', document.body.innerHTML); })()"

"(function() { processBody('" + url + "', document.body.innerHTML); })()"

"window.java.processBody('" + url + "', document.body.innerHTML);"

"processBody('" + url + "', document.body.innerHTML);"

Every time I get the error message:

I/chromium: [INFO:CONSOLE(1)] "Uncaught TypeError: processBody is not a function", source: (1)

Though on older devices (pre KitKat) the error message never shows up, the function just never gets called.

This method also had been working previously, and I do not believe I have changed any of the code for this activity. I was just made aware of the bug this morning.

I have a JavaScriptInterface class that has a single function. The function is annotated with @JavascriptInterface and I believe I have set it up correctly.

public class JavaScriptInterface {

    ...

    @JavascriptInterface
    public void processBody(String uri, String body) {
        Log.d(TAG, "Process body");
        ...
    }
}

Then I set JavaScriptEnabled on the WebView and attempt to call the function:

final WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavaScriptInterface(), "java");

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        Log.d(TAG, "Page finished");
        callJavaScript();
    }
});

The page finishes loading, then I have tried a variety of methods to call the JavaScript function from my JavaScriptInterface. Using one of these two methods:

view.evaluateJavascript(javascript);

view.loadUrl("javascript:" + javascript);

And one of these javascript strings:

"(function() { window.java.processBody('" + url + "', document.body.innerHTML); })()"

"(function() { processBody('" + url + "', document.body.innerHTML); })()"

"window.java.processBody('" + url + "', document.body.innerHTML);"

"processBody('" + url + "', document.body.innerHTML);"

Every time I get the error message:

I/chromium: [INFO:CONSOLE(1)] "Uncaught TypeError: processBody is not a function", source: (1)

Though on older devices (pre KitKat) the error message never shows up, the function just never gets called.

This method also had been working previously, and I do not believe I have changed any of the code for this activity. I was just made aware of the bug this morning.

Share Improve this question asked Jan 29, 2016 at 15:42 BryanBryan 15.2k12 gold badges74 silver badges126 bronze badges 2
  • 1 Are you using ProGuard for your app? It can strip out functions that are not called from Java. A simple test would be to add some code in Java that calls your function and see whether it helps. – Mikhail Naganov Commented Jan 29, 2016 at 19:58
  • @MikhailNaganov Ahh! Yes, I am. I must have refactored the location of my JavaScriptInterface somewhere down the line! I did not think of that, I hate that ProGuard does not follow along with refactored code! Thank you, post an answer so I can mark it as correct. – Bryan Commented Jan 29, 2016 at 20:28
Add a ment  | 

1 Answer 1

Reset to default 6

As we have figured out with Bryan, the problem was due to ProGuard stripping out functions that are not called from Java. A quick and simple test is to add some code in Java that calls the JS interface function, and see whether it helps.

For information on how to configure ProGuard not to strip out methods of injected Java objects, see How to configure proguard for javascript interface?

发布评论

评论列表(0)

  1. 暂无评论