Published: February 28, 2014
Learn how to create a new Android Project, add a Webview, load a remote URL, and load a local HTML page.
This tutorial assumes you're a developer with limited or no experience with the Android development environment, but have some experience with Kotlin. If you're already familiar with programming for Android, we recommend you read Build web apps in WebView on the Android developer site.
Install Android Studio
This tutorial uses Android Studio, the design-and-build IDE for Android.
Create a new Android Project
Once Android Studio is installed, it launches the setup wizard.
To create a new project:
- Click New Project.
- Click the Empty Activity template to select it for your project. Templates create the structure of the project and the files needed for Android Studio to build your project.
- Click Next to open the New Project dialog.
- Configure your project. Enter your application name, package name and target SDKs. Then click Next.
- Set Minimum required SDK to API 24: Android 7.0 (Nougat).
- Click Finish
Android Studio opens the new project.
Project structure
The initial project created by Android Studio has boilerplate code to set up your application. A few of the more import folders include:
src/main/java
. Android Java source code.src/main/res
. Resources used by the application.src/main/res/drawable
. Image resources used by the application.src/main/res/xml
. XML layout files that define the structure of UI components.src/main/res/values
. Dimensions, strings, and other values that you might not want to hard-code in your application.src/main/AndroidManifest.xml
. The manifest file defines what's included in the application, such as activities, permissions, and themes.
Add the WebView
Next, add a WebView to the main activity's layout.
Open the
activity_main.xml
file in thesrc/main/res/xml
directory if it is not already open. (You may also see afragment_main.xml
file. You can ignore this, as it's not required for this tutorial.)Select the Text tab at the bottom of the of the
activity_main.xml
editor to see the XML markup.This file defines the layout for your main activity, and the Preview panes show the a preview of the activity. The Blank Activity layout doesn't include any children. You'll need to add the WebView.
In the XML pane, remove the self-closing slash from the end of the
FrameLayout
element, and add the<WebView>
element and a new closing tag, as shown:<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> tools:ignore="MergeRootFrame"> <WebView android:id="@+id/activity_main_webview" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
To use the WebView you need to reference it in the Activity. Open the Java source file for the main activity,
MainActivity.java
in thesrc/main/java/<PackageName>
directory.Add the lines shown in bold.
public class MainActivity extends Activity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.activity_main_webview);
The existing code in the
onCreate
method does the work of hooking up the Activity with the layout. The added lines create a new member variable,mWebView
, to refer to the web view.Remove the following code:
if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()) .commit(); }
The WebView is identified by the resource ID, which is specified by this line in the layout file:
android:id="@+id/activity_main_webview"
After adding the code, you'll see some warning messages in the margin of the editor. This is because you haven't imported the right classes for WebView. Luckily Android Studio can help you fill in the missing classes. The easiest way to do this is click and hover over an unknown class name and wait for a module showing a "quick fix" -- in this case, adding an
import
statement for theWebView
class.Press Alt + Enter (Option + Enter on Mac) to accept the quick fix.
WebView in hand you can move on to setting it up and loading some juicy web content.
Enable JavaScript
WebView doesn't allow JavaScript by default. To run a web application in the WebView, you need to
explicitly enable JavaScript by adding the following lines to the onCreate
method:
// Enable Javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
Load a remote URL
If you're going to load data from a remote URL, your application needs permission to access the internet. This permission needs to be added in the application's manifest file.
Open the
AndroidManifest.xml
file in thesrc/res
directory. Add the line in bold before the closing</manifest>
tag.<?xml version="1.0" encoding="utf-8"?> <manifest ...> ... </application> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
The next step is to call the
loadUrl
method on the webview. Add the following line to the end of theonCreate
method.mWebView.loadUrl("[https://beta.html5test.com/][8]");
Now try running the project. If you don't have a device handy, you can create an emulator (AVD or Android Virtual Device) by going to Tools > Android > AVD Manager.
Handle navigation
Try changing the URL you're loading to https://www.css-tricks.com/
and rerun
your application. You'll notice something strange.
If you run the application now with a site that has a redirect like css-tricks.com
, your app ends
up opening the site in a browser on the device, not in your WebView -- probably not what you
expected. This is because of the way the WebView handles navigation events.
Here's the sequence of events:
- The WebView tries to load the original URL from the remote server, and gets a redirect to a new URL.
- The WebView checks if the system can handle a view intent for the URL, if so the system handles the URL navigation, otherwise the WebView navigates internally (for instance, if the user has no browser installed on their device).
- The system picks the user's preferred application for handling an
https://
URL scheme -- that is, the user's default browser. If you have more than one browser installed, you may see a dialog at this point.
If you're using a WebView inside an Android application to display content (for example, a help page), this may be exactly what you want to do. However, for more sophisticated applications, you may want to handle the navigation links yourself.
To handle navigation inside the WebView you need to override the WebView's WebViewClient
, which
handles various events generated by the WebView. You can use it to control how the WebView handles
link clicks and page redirects.
The default implementation of WebViewClient
makes any URL open in the WebView:
// Force links and redirects to open in the WebView instead of in a browser
mWebView.setWebViewClient(new WebViewClient());
This is a good step forward, but what if you want to handle links for your site only, while opening other URLs in a browser?
To achieve this you need to extend the WebViewClient
class and implement the
shouldOverrideUrlLoading
method. This method is called whenever the WebView tries to navigate to a
different URL. If it returns false, the WebView opens the URL itself. (The default implementation
always returns false, which is why it works in the previous example.)
Create a new class:
- Right-click the package name of your app and select New > Java Class
- Enter
MyAppWebViewClient
as the class name and click OK In the new
MyAppWebViewClient.java
file, add the following code (changes shown in bold):public class MyAppWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(Uri.parse(url).getHost().endsWith("css-tricks.com")) { return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); view.getContext().startActivity(intent); return true; } }
The new code defines
MyAppWebViewClient
as a subclass ofWebViewClient
and implements theshouldOverrideUrlLoading
method.The
shouldOverrideUrlLoading
method is called whenever the WebView is about to load a URL. This implementation checks for the String "css-tricks.com" at the end of the hostname of the URL. If the string exists, the method returns false, which tells the platform not to override the URL, but to load it in the WebView.For any other hostname, the method makes a request to the system to open the URL. It does this by creating a new Android Intent and using it to launch a new activity. Returning true at the end of the method prevents the URL from being loaded into the WebView.
To use your new custom WebViewClient, add the following lines to your
MainActivity
class:// Stop local links and redirects from opening in browser instead of WebView mWebView.setWebViewClient(new MyAppWebViewClient());
Now, a user can click any of the CSS Tricks links and stay within the app, but links to external sites are opened in a browser.
Handle the Android back button
As you start playing around and navigating the CSS Tricks articles, clicking the back button on Android exits the application.
The WebView method canGoBack
tells you if there is anything on the page stack
that can be popped. To detect a back button press and determine if you should
step back through the WebView's history or allow the platform to determine the
correct behaviour, add the onBackPressed()
method to your MainActivity
:
public class MainActivity extends Activity {
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
}
@Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
...
}
}
Load HTML from the file system
One big advantage of using a WebView inside an installable application is that you can store assets inside the app. This lets your app work offline and improves load times, as the WebView can retrieve assets directly from the local file system.
To store files locally, including HTML, JavaScript, and CSS, store them in the assets directory. This is a reserved directory that Android uses for raw files. Your app needs access to this directory, as it may need to minimize or compress certain files.
Create the
assets/www
directory in main (src/main/assets/www
).- It's a best practice to keep web files in a subdirectory of
/assets
.
- It's a best practice to keep web files in a subdirectory of
Upload all of the files into the directory.
Load the appropriate file:
mWebView.loadUrl("file:///android_asset/www/index.html");
Update the
shouldOverrideUrlLoading
method to open a browser for non-local pages:public class MyAppWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(Uri.parse(url).getHost().length() == 0) { return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); view.getContext().startActivity(intent); return true; } }
Now you are set to build a great WebView app.
For tips on getting the visuals just right, see Pixel-Perfect UI in the WebView.
If you run into trouble, the Chrome DevTools are your friends. See Remote Debugging on Android to get started.