Monday, February 16, 2015

Android WebView: Interacting with the Web Page from Java.

In my previous post, Android WebView: Displaying web content in your app, I explained the basic's of setting up a WebView to display web content in your app. In this post I'm going to explain how you can interact with the web page you're displaying.

It's not a good idea to try to mess with web page content for pages that you don't control because those pages can change and those changes may break your app or provide a poor user experience in your app. But there are cases when you do want to interact with web pages that you control the content of.

One example is if you provide content in your app via a web page whose content structure changes often. Using a web browser to display this data in your app provides the benefit to your users of being able to update that content without updating the app itself.

The way to accomplish this while providing a good user experience that's less likely to break when you update your web site is to define a Javascript contract for interacting with the web content. This contract is made up of a specific set of Javascript functions that your page offers the app which provides a known outcome. This allows the web page to change and add additional content while adhering to the predefined contract and gracefully failing the web page when the contract needs to change.

Executing Javascript


There are two main options you have to execute Javascript within a web page from native Java code. The option you choose will depend on what the minimum version of Android is that you are targeting in your app.

Executing Javascript on Android 4.4+


The preferred option is to use the evaluateJavascript method in the WebView class. This allows you to send some Javascript to the browser to execute and handle any expected result in native code. The  evaluateJavascript method was introduced in Android 4.4 with a new WebView class based on the Chromium.  Here's an example of how to scroll a web page to the top using this new method:

private void scrollWebPageToTop_KitKatOrAbove(WebView browser)
{
    String myScript = "window.scrollTo(0,0);";
    browser.evaluateJavascript(myScript, new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String result) {
            // Do something with the result
           Log.d("JSEXAMPLE", result);
        }
    });
}

Executing Javascript on Android 4.3 or below


If you are targeting Android 4.3 or below you'll need to use the WebView's loadUrl method to execute your Javascript. Prefacing the your URL with "javascript:" lets the WebView know that you would like to execute Javascript in the context of the current page being displayed.

private void scrollWebPageToTop_JellyBeanOrBelow(WebView browser)
{
    String myScript = "javascript:window.scrollTo(0,0);";
    browser.loadUrl(myScript);
}

The first thing you may have noticed is that you don't get the ability to deal with the result of the Javascript method you just executed. If you are executing Javascript from which you expect a result you'll need to use the WebView's addJavascriptInterface method and explicitly call the callback you've registered. Next week's post will go into greater detail on using this method to allow your web page to trigger native Java code to deal with the result of your Javascript code execution.

For more information on the new WebView based on the Chromium browser see the Migrating to WebView in Android 4.4 page in the Web Apps section of the Android developer guides.

1 comment: