WebView is widely used in the Android development process, commonly used to load web pages, such as using WebView to load news pages, open links to this application using WebView, and display payment information pages using WebView. So how to interact with the content in WebView in Android development? This interaction is mainly the mutual invocation between Java and JavaScript. The following implements how to respond to the click event of an image in WebView, the main content is as follows:
- Key methods
- Specific implementation
- Display effect
Key methods#
setJavaScriptEnabled()#
Set whether WebView supports JavaScript scripts, which is not supported by default.
public abstract void setJavaScriptEnabled(boolean flag);
addJavascriptInterface()#
Inject Java objects into WebView, which will be injected into the context of the JavaScript main framework, allowing JavaScript to access the methods of the mapped Java objects using the name of the Java objects, and only public methods with the @JavascriptInterface annotation can be accessed from JavaScript. This can be used above API level 17.
For API level 16 and earlier APIs, all public methods (including inherited ones) can be accessed from JavaScript, and there may be a situation where the Java objects have not been injected into JavaScript before the page is reloaded, resulting in the Java methods not taking effect.
Important Note: This method allows JavaScript to control the application, which is very powerful, but there may be certain risks for API level 16 and earlier versions. The safer approach is to use this method as much as possible in Android 4.2 and above. If it is a lower version, JavaScript can use reflection to access the public fields of the injected objects. Using this method in WebView may allow attackers to exploit untrusted content and make the application execute Java code. Pay attention to thread safety, and the fields of Java objects are not accessible. For API level 5.0 and above, there are certain limitations on the number of methods that can be injected into JavaScript.
public void addJavascriptInterface(Object object, String name) {}
Specific implementation#
The general idea is to make the images in WebView respond to click events, and then call the Android interface to display the clicked image. The implementation steps are as follows:
- Set WebView to support JavaScript scripts;
- Create a class for communication with JavaScript and methods callable by JavaScript;
- Load the content to be displayed in WebView;
- Use the addJavascriptInterface method to map the Java object to JavaScript;
- Call the methods of the mapped object in JavaScript to open the activity that displays the image;
- Call the method in JavaScript.
Step 1#
Set WebView to support JavaScript scripts, as follows:
// Enable JavaScript
webSettings.setJavaScriptEnabled(true);
Step 2#
Create a Java object for communication with JavaScript and methods callable by JavaScript, as follows:
/**
* Java object for communication with JavaScript, providing methods callable by JavaScript
* Created by jzman on 2017/7/20 0020.
*/
public class AndroidInterface {
private Context context;
public AndroidInterface(Context context) {
this.context = context;
}
/**
* Add the @JavascriptInterface annotation
* Method to be called by JavaScript
*/
@JavascriptInterface
public void showImage(String imgUrl){
Intent intent = new Intent();
intent.putExtra("img",imgUrl);
intent.setClass(context,ImageActivity.class);
context.startActivity(intent);
}
}
Step 3#
Load the content to be displayed in WebView, here we load the HTML file in the assets directory, as follows:
// Load HTML file in the assets directory
webView.loadUrl("file:///android_asset/index.html");
Step 4#
Use the addJavascriptInterface method to map the Java object to JavaScript, as follows:
// Inject Java object and map it to JavaScript
// Parameters (object for communication with JavaScript, object mapped to JavaScript)
webView.addJavascriptInterface(new AndroidInterface(this),"imageListener");
Step 5#
In JavaScript, find the tag and call the method of the mapped object in its click event to open the activity that displays the image, as follows:
<script type="text/javascript">
function findImg(){
// Find the img tag
var imgs = document.getElementsByTagName("img");
// Traverse the img tags
for(var i=0; i<imgs.length; i++){
// Set click event for each tag
imgs[i].onclick = function(){
// imageListener is the mapped Java object
window.imageListener.showImage(this.src);
}
}
}
</script>
Step 6#
Call the method in JavaScript. To ensure that the Java object has not been injected into JavaScript when calling, the JavaScript method should be called when the page is loaded, as follows:
// Set WebViewClient to listen for relevant events
webView.setWebViewClient(new WebViewClient(){
// Callback method when the page is loaded
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// Ensure that the Java object is injected into JavaScript after the page is loaded
webView.loadUrl("javascript:findImg()");
}
});
Display effect#
Please refer to the source code on GitHub for the code.