JavaScript Interface in Android WebView: Complete Tutorial
In this tutorial, you will learn how to call Android Java code from
JavaScript inside a WebView using the
addJavascriptInterface() method. This is the standard technique used in
Android hybrid apps that combine a WebView (HTML + CSS + JS) with native Android
features.
You will build a small app where a button click in the HTML triggers a native Android
AlertDialog — demonstrating the full JavaScript ↔ Java bridge.
Overview
The Android WebView allows you to display web content inside your app. But WebView alone is limited — it cannot access native Android features like dialogs, camera, or file system.
addJavascriptInterface() bridges that gap. It exposes a Java object to the
JavaScript running inside the WebView, letting JavaScript call Java methods directly.
What you will build:
- A WebView that loads a local HTML page
- An HTML button that calls a Java method via JavaScript
- A native Android AlertDialog that appears when the button is clicked
MainActivity.java
The activity enables JavaScript, registers a custom JSCode object as the
JavaScript interface, and loads a local HTML file from the assets folder.
package example.deepsingh44.com.webviewjs;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
private JSCode js;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView web = findViewById(R.id.web);
String file = "file:///android_asset/test.html";
// Enable JavaScript (disabled by default)
web.getSettings().setJavaScriptEnabled(true);
// Register the Java object exposed to JavaScript
js = new JSCode(this);
web.addJavascriptInterface(js, "call");
// Load the local HTML file
web.loadUrl(file);
}
/**
* Java class exposed to JavaScript. Any public method
* annotated with @JavascriptInterface can be called from JS.
*/
public class JSCode {
private Context mContext;
public JSCode(Context c) {
mContext = c;
}
@JavascriptInterface
public void show(String toast) {
AlertDialog.Builder a = new AlertDialog.Builder(mContext);
a.setTitle("Alert Message");
a.setMessage("Good Morning");
a.setCancelable(false);
a.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
a.show();
}
}
}
Key points:
setJavaScriptEnabled(true)— required for JavaScript to run at all.addJavascriptInterface(js, "call")— exposes theJSCodeobject under the namecallin JavaScript.@JavascriptInterface— required annotation on every method that JavaScript can call.loadUrl("file:///android_asset/...")— loads a file bundled inside your APK.
activity_main.xml
A simple full-screen WebView layout.
<?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/web"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Note: Your original file had a typo — the opening
<LinearLayout> was closed with /> instead of
>. This would cause a compile error. Fixed above.
test.html
Place this file in the assets/ folder of your project. It contains a
JavaScript function that calls call.show() — the Java method exposed to the
WebView.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Interface Demo</title>
<script type="text/javascript">
function get() {
call.show("Hello");
}
</script>
</head>
<body>
<form>
<div align="center">
<input onclick="get()" type="button" value="Click me" />
</div>
</form>
</body>
</html>
Important fixes in this file:
-
Your original had
<script type="text/javascript"without a closing>. Fixed. -
Your original had
<div align="center" <input ...— the<input>tag was written inside the<div>opening tag by mistake. Fixed.
How It Works (Step-by-Step)
-
Activity launches —
activity_main.xmlis inflated, showing a full-screen WebView. -
JavaScript is enabled — by default WebView blocks JavaScript.
Calling
setJavaScriptEnabled(true)allows the HTML page to run its scripts. -
Java bridge is registered —
addJavascriptInterface(js, "call")exposes theJSCodeobject to JavaScript under the namecall. -
Local HTML is loaded —
file:///android_asset/test.htmlloads the HTML page from the APK's assets folder. -
User taps the button — the HTML button's
onclickcalls the JavaScript functionget(). -
JavaScript calls Java —
call.show("Hello")invokes theshow()method on the registered Java object. -
Native dialog appears — the Java method runs on Android's main
thread, showing a native
AlertDialogwith the message "Good Morning".
Security Considerations
addJavascriptInterface() is powerful but carries real security risks. Follow
these rules:
-
Only load trusted content — never use
addJavascriptInterfacewith pages from the internet. An attacker controlling the page can call your Java methods. -
Annotate every exposed method with
@JavascriptInterface— without it, the method cannot be called. This is your allow-list. - Never expose sensitive data — do not pass credentials, tokens, or file system access through the interface.
-
Prefer local assets — in this tutorial, we load
file:///android_asset/test.html, which lives inside your APK and cannot be tampered with by an attacker. - Validate all input — if your Java method accepts a String from JavaScript, sanitize it before using it.
Customization Ideas
-
Pass data back to JavaScript — call
webView.evaluateJavascript("updateUI('...')", null)from Java to invoke JavaScript functions. -
Show a Toast instead of a dialog — replace
AlertDialogwithToast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(). -
Read a value from JavaScript — pass a callback name and invoke it
via
evaluateJavascript()after the Java method completes. -
Load a remote HTML page — use
webView.loadUrl("https://yoursite.com"). Be careful withaddJavascriptInterfacein this case. -
Migrate to AndroidX — replace
android.support.v7.app.AppCompatActivitywithandroidx.appcompat.app.AppCompatActivity, andandroid.support.v7.app.AlertDialogwithandroidx.appcompat.app.AlertDialog. -
Use WebViewClient — override
shouldOverrideUrlLoading()to intercept URL changes.
Frequently Asked Questions
What is addJavascriptInterface in Android WebView?
addJavascriptInterface is a WebView method that exposes a Java object to
JavaScript running inside the WebView. JavaScript can then call public methods of that
Java object using the name you assigned. It is the standard way to bridge JavaScript and
native Android code in hybrid apps.
Why do I need @JavascriptInterface annotation?
The @JavascriptInterface annotation marks which Java methods are exposed to
JavaScript. Without it, the method cannot be called from the WebView — this is a security
measure to prevent accidental exposure of every public method.
Is addJavascriptInterface safe?
addJavascriptInterface is only safe when loading trusted content. If you
load untrusted web pages, an attacker could use the interface to call native Java methods
and steal data or execute code. Only use it with pages you control (like local assets).
How do I load a local HTML file in Android WebView?
Place the HTML file in the assets/ folder of your project, then call
webView.loadUrl("file:///android_asset/filename.html"). This loads the file
from within the APK without needing an internet connection.
Why does my WebView JavaScript not work?
By default, JavaScript is disabled in WebView for security. You must
call webView.getSettings().setJavaScriptEnabled(true) before loading the
page.
Conclusion
In this tutorial, you learned how to call native Android Java code from
JavaScript inside a WebView using addJavascriptInterface(). You
built a working example where an HTML button click triggers a native Android
AlertDialog — the same pattern used in hybrid apps built with Cordova,
Capacitor, or custom WebView wrappers.
The JavaScript interface is powerful but must be used carefully — always load trusted
content, annotate every exposed method with @JavascriptInterface, and never
expose sensitive functionality.
Related topics: Android WebView Introduction, WebView with JavaScriptEnabled, Android AlertDialog Tutorial, Android Toast Tutorial, WebViewClient vs WebChromeClient, Android Hybrid App Development