Understanding Android WebViews

Share this article

Android provides a variety of views to build the UI of your application. One example is WebView, views which can be embedded in your Activities and used to display Web pages. The ability to display web pages in your activity has a lot of advantages as it helps reuse Web pages and Web apps in an Android app. The content of the Web page can be controlled and changed from the server directly. This is useful for pages like user agreements and terms and conditions that require only periodic changes. Webview is useful for responsive design and situations where you need to load an external page which is not under your control and does not have a public android intent exposed.

This article shows you through how to embed a WebView in your activity to display Web page.

Embedding a WebView in your activity to display a web page.

Let’s start by adding the WebView to an activity. To add a WebView to a layout xml, use the following code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <WebView
      android:id="@+id/webview"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
  />
</LinearLayout>

In the code above I created a linear layout which will be a container view to hold the WebView. Inside the linear layout, I added a WebView to load a Web page via URL. As loading the Webpage via URL requires an internet connection, add the following permission to AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

Once the layout and permission is defined, create an activity which will use this layout and load the Web page:

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

public class WebVievActivityWithURL extends Activity {

    private WebView myWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_with_web_view);

        myWebView = (WebView) findViewById(R.id.webview);

        myWebView.loadUrl("https://m.facebook.com");
    }

}

In the code above, the onCreate of the activity set the content view as the layout defined and then gets the WebView using the function findViewById. The loadUrl function then loads the url into the WebView. Once complete and the activity launches, you should see the web page loaded.

Facebook login screen

Embedding a WebView in your activity to display static HTML.

In some cases you might not want to load a Web page from an URL but directly load HTML content into the WebView. WebView provides functionality to do this using the loadDataWithBaseURL function:

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

public class WebViewActivityWithHTML extends Activity {

    private WebView myWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_with_web_view);

        myWebView = (WebView) findViewById(R.id.webview);
        myWebView.loadDataWithBaseURL("file:///android_asset/", getHTMLData(),
                "text/html", "UTF-8", "");
    }

    private String getHTMLData() {
        StringBuilder html = new StringBuilder();
        html.append("<html>");
        html.append("<head>");

        html.append("<link rel=stylesheet href='css/style.css'>");
        html.append("</head>");
        html.append("<body>");
        html.append("<div id ='main'> Loading html data in WebView</div>");
        html.append("</body>");
        html.append("</html>");

        return html.toString();
    }
}

The WebViewActivityWithHTML activity above uses the same activity_with_web_view layout which already defined. In the onCreate function, the reference to the WebView appears again. Use this to call loadDataWithBaseURL, which takes the base_url used for all relative paths in the HTML content.

Next, pass file:///android_asset/ for the CSS to be detected. The second parameter is the HTML data. The other parameters are the mime type, character encoding and history url.

To avoid passing the base URL, use the function loadData which takes three parameters: data, mimetype and character encoding.

I have referred to css/style.css in the HTML. To create this, add a directory called css in the assets folder and a style.css file inside that with the following content:

#main {
    color: #00ff00;
}

Once WebViewActivityWithHTML launches, the WebView loads with the static HTML.

Loading WebView

Handling navigation in WebViews

When using WebViews, callbacks might be required during the loading of a Web page. For example, when a link is clicked in the WebView, Android performs the default action, which is likely opening the URL in a different browser.

To override this and load the URL in the WebView itself, provide a WebViewClient instance in the WebView which will handle callbacks:

import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class WebViewActivityWithWebClient extends Activity {

    private WebView myWebView;

    /** (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_with_web_view);

        myWebView = (WebView) findViewById(R.id.webview);
        myWebView.setWebViewClient(new MyWebViewClient());

        myWebView.loadData(getHTMLData(),"text/html", "UTF-8");
    }

    /**
     * @return - Static HTML data
     */
    private String getHTMLData() {
        StringBuilder html = new StringBuilder();
        html.append("<html>");
        html.append("<head>");
        html.append("</head>");
        html.append("<body>");
        html.append("<div id ='main'> <a href ='https://m.facebook.com'> Go to Face book</a></div>");
        html.append("</body>");
        html.append("</html>");

        return html.toString();
    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
           view.loadUrl(url);
           return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            //You can add some custom functionality here
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
          //You can add some custom functionality here
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
          //You can add some custom functionality here
        }
     }

}

The above code sets a custom WebView client which overrides the shouldOverrideUrlLoading function and loads the URL right into the WebView rather than another browser and then returns true to signify that it will override the url loading. If we run this activity and click on the Go to Facebook link it will open the Facebook link right in the WebView.

There are other callbacks such as onPageStarted, onPageFinished and onReceivedError which can be used for different kinds on processing based on app requirements.

Opening a Link

Injecting JavaScript in WebViews

When building more complex Web pages for mobile you might need to call some native methods from your Web page. To do this in a WebView, enable the JavaScript setting in the WebView and provide a class which will expose methods to call from JavaScipt:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;

public class WebViewActivityWithJavaScript extends Activity {
    private WebView myWebView;

    /* (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_with_web_view);

        myWebView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        myWebView.addJavascriptInterface(new MyJavaScriptInterface(this), "Android");
        myWebView.loadData(getHTMLData(),"text/html", "UTF-8");
    }

    /**
     * @return - Static HTML data
     */
    private String getHTMLData() {
        StringBuilder html = new StringBuilder();
        try {
            AssetManager assetManager = getAssets();

            InputStream input = assetManager.open("javascriptexample.html");
            BufferedReader  br = new BufferedReader(new InputStreamReader(input));
            String line;
            while ((line = br.readLine()) != null) {
                html.append(line);
            }
            br.close();
        } catch (Exception e) {
           //Handle the exception here
        }

        return html.toString();
    }

    public class MyJavaScriptInterface {
        Activity activity;

        MyJavaScriptInterface(Activity activity) {
            this.activity = activity;
        }

        @JavascriptInterface
        public void showToast(String toast) {
            Toast.makeText(activity, toast, Toast.LENGTH_SHORT).show();
        }

        @JavascriptInterface
        public void closeActivity() {
            activity.finish();
        }
    }
}

In the code above, WebSettings of the WebView are revealed by calling the getSettings method and enabling JavaScript using the method setJavaScriptEnabled.

Then call the addJavascriptInterface method and pass it an object and a string. The string can be used to call methods on the object which have the annotation @JavascriptInterface. In the MyJavaScriptInterface class are two methods: showToast, which shows an Android toast and closeActivity, which finishes the activity.

In the above example, loadData loads the webpage (loadUrl could load a Web page from an url) which fetches the HTML in the getHTMLData function from javascriptexample.html in the assets folder.

Create the file javascriptexample.html in the assets folder:

<html>

<body>
<input type="button" value="Show Toast" onClick="showAndroidToast('Toast to JavaScript interface')" />
<br>
<input type="button" value="Close this Activity" onClick="closeActivity()" />
</body>
<script type="text/javascript">
    function showAndroidToast(toast) {
        Android.showToast(toast);
    }

     function closeActivity() {
        Android.closeActivity();
    }
</script>

</html>

The code above creates two buttons, which when clicked call a Javascript function. These in turn call the JavaScipt interface functions which we exposed. If we run this activity and click on Show Toast, the toast is shown.

Android Toast

Conclusion

WebViews in Android provide a rich set of functionality and are important in building an app which needs to load external Web pages or HTML data. WebViews provide interesting methods for Web pages to interact with the Android app using the JavaScript interface.

Have fun using the WebView in your next Android app and please let me know if you have any questions or comments.

Frequently Asked Questions (FAQs) about Android WebViews

What is the main purpose of Android WebView?

Android WebView is a system component powered by Chrome that allows Android apps to display web content. This component is pre-installed on your device and should be kept up to date to ensure you have the latest security updates and other bug fixes. It’s essentially a mini browser that you can embed within your Android apps to display web pages without having to switch to a full-fledged browser app.

How can I enable JavaScript in Android WebView?

To enable JavaScript in Android WebView, you need to use the setJavaScriptEnabled(true) method. Here’s a simple example:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
Remember that enabling JavaScript can lead to some security issues, so only enable it when you know the web content is safe.

How can I load a local HTML file in Android WebView?

To load a local HTML file in Android WebView, you can use the loadUrl() method with the “file:///android_asset/” prefix. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("file:///android_asset/myfile.html");
This will load the “myfile.html” file located in the “assets” folder of your Android project.

How can I handle page navigation in Android WebView?

To handle page navigation in Android WebView, you can override the shouldOverrideUrlLoading() method of WebViewClient. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
This will make all links load within the WebView instead of launching the default browser.

How can I enable zoom controls in Android WebView?

To enable zoom controls in Android WebView, you can use the setBuiltInZoomControls(true) method. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setBuiltInZoomControls(true);
This will enable the built-in zoom controls. Note that pinch-to-zoom will also be enabled by default.

How can I clear the cache of Android WebView?

To clear the cache of Android WebView, you can use the clearCache() method. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.clearCache(true);
This will clear the cache of the WebView. The parameter indicates whether disk cache should also be cleared.

How can I handle SSL errors in Android WebView?

To handle SSL errors in Android WebView, you can override the onReceivedSslError() method of WebViewClient. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // Ignore SSL certificate errors
}
});
This will ignore SSL certificate errors. Note that this can lead to security issues, so only use it when you know the web content is safe.

How can I execute JavaScript code in Android WebView?

To execute JavaScript code in Android WebView, you can use the evaluateJavascript() method. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.evaluateJavascript("javascript:alert('Hello, World!')", null);
This will execute the JavaScript alert() function with the message “Hello, World!”.

How can I load a URL in Android WebView?

To load a URL in Android WebView, you can use the loadUrl() method. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("https://www.example.com");
This will load the specified URL in the WebView.

How can I handle errors in Android WebView?

To handle errors in Android WebView, you can override the onReceivedError() method of WebViewClient. Here’s an example:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
Toast.makeText(getApplicationContext(), "Error: " + error.getDescription(), Toast.LENGTH_SHORT).show();
}
});
This will display a toast message with the error description whenever an error occurs.

Abbas SuterwalaAbbas Suterwala
View Author

Abbas is a software engineer by profession and a passionate coder who lives every moment to the fullest. He loves open source projects and WordPress. When not chilling around with friends he's occupied with one of the following open source projects he's built: Choomantar, The Browser Counter WordPress plugin, and Google Buzz From Admin.

chriswwebview
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week