Android provides a very powerful WebView control for processing Web pages, and in the web page, JavaScript is also a very important script. This article will introduce how to implement mutual calls between Java code and Javascript code.
It is very convenient to realize the interaction between Java and js. Usually only the following steps are required.
WebView enables JavaScript script execution
WebView sets the interactive interface for JavaScript calls.
The client and the web page write code to call each other.
For the convenience of explanation, all the code is posted first
Java code
package com.example.javajsinteractiondemo; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.webkit.JavascriptInterface; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends Activity { private static final String LOGTAG = "MainActivity"; @SuppressLint("JavascriptInterface") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final WebView myWebView = (WebView) findViewById(R.id.myWebView); WebSettings settings = myWebView.getSettings(); settings.setJavaScriptEnabled(true); myWebView.addJavascriptInterface(new JsInteration(), "control"); myWebView.setWebChromeClient(new WebChromeClient() {}); myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); testMethod(myWebView); } }); myWebView.loadUrl("file:///android_asset/js_java_interaction.html"); } private void testMethod(WebView webView) { String call = "javascript:sayHello()"; call = "javascript:alertMessage(\"" + "content" + "\")"; call = "javascript:toastMessage(\"" + "content" + "\")"; call = "javascript:sumToJava(1,2)"; webView.loadUrl(call); } public class JsInteration { @JavascriptInterface public void toastMessage(String message) { Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } @JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); } } }
Front-end web page code
<html> <script type="text/javascript"> function sayHello() { alert("Hello") } function alertMessage(message) { alert(message) } function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) } </script> Java-Javascript Interaction In Android </html>
The calling format is window.jsInterfaceName.methodName(parameterValues) In this example we use control as the injection interface name.
function toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
The basic format of webView calling js is webView.loadUrl("javascript:methodName(parameterValues)")
String call = "javascript:sayHello()"; webView.loadUrl(call);
Note that strings need to be escaped in double quotes as parameter values.
String call = "javascript:alertMessage(\"" + "content" + "\")"; webView.loadUrl(call);
Before 4.4, Android did not provide a method to directly call js functions and obtain values, so before that, the common idea was to call java js method, after the js method is executed, call the java code again to return the value.
1.Java calls js code
String call = "javascript:sumToJava(1,2)"; webView.loadUrl(call);
2.js function processing and returns the result by calling the java method
function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
3.Java obtains the js function in the callback method Return value
@JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); }
Use evaluateJavascript after Android 4.4. Here is a simple interactive example of a js method with a return value
function getGreetings() { return 1; }
Use the evaluateJavascript method to call when using java code
private void testEvaluateJavascript(WebView webView) { webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.i(LOGTAG, "onReceiveValue value=" + value); }}); }
Output results
I/MainActivity( 1432): onReceiveValue value=1
Note
The above limits the return result to String. For simple types, it will be converted into a string and returned. For complex data types, it is recommended to use the string form jsonreturn.
evaluateJavascript method must be called on the UI thread (main thread), so onReceiveValue is also executed on the main thread.
You should not have set up WebChromeClient, follow the following code to set it up
myWebView.setWebChromeClient(new WebChromeClient() {});
The reason for the problem is that the js code of the webpage has not been loaded, so the js method is called. The solution is to call the js method after the web page is loaded.
myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //在这里执行你想调用的js函数 } });
If the problem only occurs on machines with version 4.2 or above, then the problem is that the system is under security restrictions. The Android documentation says this
Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available your web page code (the method must also be public). If you do not provide the annotation, then the method will not accessible by your web page when running on Android 4.2 or higher.
中文译为
Warning: If your program targets platform 17 or higher, you must add @JavascriptInterface annotation to the method exposed to the web page callable (this method must be public). If you don't do this, the web page will not be able to access your method on platforms 4.2 and later.
Set targetSdkVersion to 17 or higher and introduce @JavascriptInterface annotation
Create an annotation interface named @JavascriptInterface yourself, and then import it. Note that this interface cannot be confused.
Note, create @JavascriptInterface code
public @interface JavascriptInterface { }
If the code in the unobfuscated version runs normally, the code in the obfuscated version A running error occurs and the message Uncaught TypeError: Object [object Object] has no method means that you have not done any obfuscating exception handling. Add code similar to this to the obfuscation file
-keep class com.example.javajsinteractiondemo$JsInteration { *; }
Filter logs have discovered this problem.
E/StrictMode( 1546): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c}, FYI main Looper is Looper (main, tid 1) {528712d4}) E/StrictMode( 1546): at android.webkit.WebView.checkThread(WebView.java:2063) E/StrictMode( 1546): at android.webkit.WebView.loadUrl(WebView.java:794) E/StrictMode( 1546): at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27) E/StrictMode( 1546): at android.os.Handler.dispatchMessage(Handler.java:102) E/StrictMode( 1546): at android.os.Looper.loop(Looper.java:136) E/StrictMode( 1546): at android.os.HandlerThread.run(HandlerThread.java:61)
The Java callback thread after the js call is not the main thread. If you print the log, you can verify
ThreadInfo=Thread[WebViewCoreThread,5,main]
To solve the above exception, just put the webview operation in the main thread.
webView.post(new Runnable() { @Override public void run() { webView.loadUrl(YOUR_URL). } });
The above is the detailed content of Detailed explanation of Java and JavaScript interaction in Android. For more information, please follow other related articles on the PHP Chinese website!