8

I'm trying to add a javascript interface to a WebView I've found. I followed all the standard tutorial and still getting struggled with the task. When adding the javascript interface, I don't get any exceptions or errors, but when explicitly calling the bridge from JS, I get the following error:

I/chromium: [INFO:CONSOLE(1)] "Uncaught ReferenceError: JSNativeBridge is not defined", source:  (1)

Adding the javascript interface:

new Handler(context.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        WebView webView = webViews[0];
        if (Constants.DEBUG_MODE) {
            webView.setWebChromeClient(new WebChromeClient());
            webView.getSettings().setJavaScriptEnabled(true);
        }
        ImpressionSyncJsInterface impressionSyncJsInterface = new ImpressionSyncJsInterface(context);
        webView.addJavascriptInterface(impressionSyncJsInterface, JS_BRIDGE_NAME);
        didAddInterfaceToWebView = true;
    }
});

My interface:

public class ImpressionSyncJsInterface {
    private final Context context;

    public ImpressionSyncJsInterface(Context context) {
        this.context = context;
    }

    @JavascriptInterface
    public void foo() {
        Log.e("TEST", "test");
    }
}

The Javascript execution:

final String javascriptInjectionTest = "javascript: " + JS_BRIDGE_NAME + ".foo();";

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        webView.loadUrl(javascriptInjectionTest);
    }
});
2
  • 1
    Please put the javascript code, from where you are calling java class. Commented Jan 25, 2016 at 3:44
  • I don't see any code loading a page prior to trying to access the injected object. You need to load some page first, see developer.android.com/reference/android/webkit/… Commented Jan 25, 2016 at 21:44

1 Answer 1

27

Figured out the problem, so I'll share my insights:

The addJavascriptInterface function applies only if called BEFORE a loadUrl / loadData function.

In my case - I expected addJavascriptInterface to inject a JS bridge, but I never reloaded the WebView content, so it was never actively injected.

After reloading the WebView HTML content, the bridge was added as expected.

Sign up to request clarification or add additional context in comments.

3 Comments

You should accept this as your own answer so other folks can find it more easily I just ran into the same thing myself!
thanks I found it states this in the docs: developer.android.com/reference/android/webkit/… Note that injected objects will not appear in JavaScript until the page is next (re)loaded.
Thanks for that answer. The "BEFORE a loadUrl" allowed me to realize that I was adding the interface inside onPageStarted() method of WebViewClient lifecycle, which made it work in some Android phones and not in others. I moved it outside, after webView.setWebViewClient() and before webView.loadUrl().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.