preface
This article explains how Java code and Javascript code call each other and how Javascript code is dynamically injected into a WebView in Java. Some common configurations are described in Part 1.
Java calls JS functions
1. Add permissions (here using HTML files written in the resources directory)
<uses-permission android:name="android.permission.INTERNET"/>Copy the code
2. The webView configuration
.// omit findView.. webview
mWebView.getSettings().setJavaScriptEnabled(true);Copy the code
3. The use ofwebView
theloadUrl()
Method calls a JS function
Note that the function is preceded by javascript:
. btn_invoke_js1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Call a function with no arguments in JS
mWebView.loadUrl("javascript:javacalljs()");
mWebView.loadUrl("Javascript: javacalljswith (\" JAVA calls the JS function refs \ ")"); }}); .Copy the code
JS calls methods in Java
1. Add the js callback interface
The first argument is the class to receive the callback, written as the current class, and then the method called by JS is added to the current class. Obj is an alias, the same as in JS.
mWebView.addJavascriptInterface(this."obj");Copy the code
2. Add methods called by JS to Java.
Note that you must not forget to add @javascriptInterface to the method here and the window.obj.localMethods(‘Incoming ‘in web.html Parameters ‘) remain consistent.
.@JavascriptInterface
public void localMethods(String arg) {
Log.i(TAG, "This method is called!");
Toast.makeText(this."This method is called!", Toast.LENGTH_SHORT).show();
}Copy the code
Dynamic JS injection in Java
1. Inject JS methods
Here the injection time is after onPageFinished(); The injected JS is an alert for example.
public class JsInjectionActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {... InsideWebViewClient mInsideWebViewClient =new InsideWebViewClient();
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setWebViewClient(mInsideWebViewClient);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(JsInjectionActivity.this."obj");
mWebView.loadUrl("file:///android_asset/web.html"); . }private class InsideWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
mWebView.loadUrl("javascript:" + "window.alert('Js injection success')" );
super.onPageFinished(view, url); }}}...Copy the code
Note: the js injected above contains an alert, which may not pop up after writing. At this time to check myWebView. SetWebChromeClient (new WebChromeClient ()); Whether it is set.
2. (Emphasis) Problems caused or possible problems caused by injected JS
- injection
js
It might cause a loadhtml5
Pages are always loading, loading slowly or not loading at all, and this problem is not universalhtml5
You may encounter this problem on some web pages; - The callback function is not executed after JS injection.
Solutions:
@Override
protected void onPause(a){
super.onPause();
mWebView.pauseTimers();
if(isFinishing()){
mWebView.loadUrl("about:blank");
setContentView(new FrameLayout(this)); }}@Override
protected void onResume(a){
super.onResume();
mWebView.resumeTimers();
}Copy the code
Call the webView. LoadUrl (” about: blank “); This method causes the webView to return only a white background, frees the resources used to load the page, and stops the javascript execution.
PauseTimers, onPause stop parsing,javascript execution, etc. The difference is that onPause only works on the WebView that calls it, while pauseTimers work on all webViews in the current application
ResumeTimers, onResume resume parsing,javascript execution and other operations. The difference is that onResume only applies to the WebView that calls it, while resumeTimers apply to all webViews in the current application.
3. When the compressed JS is injected into the webView, the injection does not take effect
My solution: inject the JS formatted or uncompressed state successfully, I don’t know if others have encountered similar problems, or other reasons, there are questions, if you have encountered the same problem, welcome to communicate with you.
Online js formatting, four Spaces indentation indentation method choice: tool.oschina.net/codeformat/…
4. Complete code
Complete code, does not contain JS injection encountered the problem part, to join.
1. web.html
file
File path:.. src/main/assets/web.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<script type="text/javascript">
function javacalljs(a){
document.getElementById("content").innerHTML =
JAVA calls JS functions without arguments;
}
function javacalljswith(arg){
document.getElementById("content").innerHTML = ("<br>"+arg); } </script> </head> <body> HTML content display <br/> <h1> <div id="content"</div> </h1> <br/> <input type="button" value="Click to call Java code" onclick="window.obj.localMethods('Incoming parameters')"/><br/>
</body>
</html>Copy the code
2. JsInjectionActivity.java
file
public class JsInjectionActivity extends Activity {
private static final String TAG = JsInjectionActivity.class.getSimpleName();
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_invoke_js1 = (Button) findViewById(R.id.btn_invoke_js1);
Button btn_invoke_js2 = (Button) findViewById(R.id.btn_invoke_js2);
mWebView = (WebView) findViewById(R.id.webview);
InsideWebViewClient mInsideWebViewClient = new InsideWebViewClient(a); mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setWebViewClient(mInsideWebViewClient);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(JsInjectionActivity.this."obj");
mWebView.loadUrl("file:///android_asset/web.html");
btn_invoke_js1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mWebView.loadUrl("javascript:javacalljs()"); }}); btn_invoke_js2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mWebView.loadUrl("Javascript: javacalljswith (\" JAVA calls the JS function refs \ ")"); }}); }@JavascriptInterface
public void localMethods(String arg) {
Log.i(TAG."This method is called!");
Toast.makeText(this."This method is called!".Toast.LENGTH_SHORT).show();
}
private class InsideWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
mWebView.loadUrl("javascript:" + "window.alert('Js injection success')" );
super.onPageFinished(view, url); }}}Copy the code
The last
If you don’t know the place, you are welcome to send me a private letter. I will reply you in the first time. If you find something wrong in your reading, you are welcome to correct it.