Android provides a powerful WebView control for working with Web pages, and JavaScript is a very important script in Web pages. This article describes how to implement mutual invocation of Java code and JavaScript code.
How to Achieve
Java and JS to implement the interaction is very convenient. Typically, only the following steps are required.
1.WebView Open JavaScript Script execution
2.WebView sets the interactive interface for JavaScript invocation.
3. The client and the Web end write the code that invokes the other.
This example code
In order to facilitate the explanation, first pastes the entire code
Java code
Copy Code code as follows:
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 page code
Copy Code code as follows:
<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
Call Example
JS calls Java
Call format is Window.jsInterfaceName.methodName (parametervalues) In this case, we use control as the injection interface name.
Copy Code code as follows:
function toastmessage (message) {
Window.control.toastMessage (Message)
}
function Sumtojava (Number1, number2) {
Window.control.onSumResult (Number1 + number2)
}
Java Call JS
WebView Call JS basic format for Webview.loadurl ("Javascript:methodname (parametervalues)")
Call JS no parameter return value function
Copy Code code as follows:
String call = "Javascript:sayhello ()";
Webview.loadurl (call);
Call JS parameter without return value function
Note You need to escape double quotes for strings as parameter values.
Copy Code code as follows:
String call = "Javascript:alertmessage (\" + "content" + "\") ";
Webview.loadurl (call);
Call JS has a function with the return value of the parameter
Android before 4.4 did not provide a direct call to the JS function and get the value of the method, so before this, the common idea is Java calls the JS method, the JS method is finished, call the Java code again to return the value.
1.Java Call JS Code
Copy Code code as follows:
String call = "Javascript:sumtojava (1,2)";
Webview.loadurl (call);
2.js function and returns the result by invoking the Java method
Copy Code code as follows:
function Sumtojava (Number1, number2) {
Window.control.onSumResult (Number1 + number2)
}
3.Java gets the return value of the JS function in the callback method
Copy Code code as follows:
@JavascriptInterface
public void Onsumresult (int result) {
LOG.I (LogTag, "Onsumresult result=" + result);
}
4.4 Processing
After Android 4.4, you can use Evaluatejavascript. Here's a simple interaction example. js method with return value
Copy Code code as follows:
function Getgreetings () {
return 1;
}
Java code is invoked using the Evaluatejavascript method
Copy Code code as follows:
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
Copy Code code as follows:
I/mainactivity (1432): Onreceivevalue value=1
Attention
1. The result is defined as String, the simple type attempts to convert to a string return, and for complex data types, it is recommended that JSON be returned in string form.
The 2.evaluateJavascript method must be invoked on the UI thread (the main thread), so Onreceivevalue also executes on the main thread.
Question Answer
Alert cannot eject
You should be not set webchromeclient, follow the code set below
Copy Code code as follows:
Mywebview.setwebchromeclient (New Webchromeclient () {});
Uncaught Referenceerror:functionname is not defined
The problem occurs, the page's JS code did not load complete, it called the JS method. The solution is to call the JS method after the Web page has finished loading
Copy Code code as follows:
Mywebview.setwebviewclient (New Webviewclient () {
@Override
public void onpagefinished (webview view, String URL) {
super.onpagefinished (view, URL);
Execute the JS function you want to call here
}
});
Uncaught Typeerror:object [Object Object] has no method
Security restrictions issues
If only the machines in the 4.2 version of the problem, then the system is in the security constraints. The Android document says so
Copy Code code as follows:
Caution:if you ' ve set your targetsdkversion to "or higher, you must add the @JavascriptInterface annotation to any meth OD this you want available your Web page code (the method must also is public). If you don't provide the annotation, then the method won't accessible by your Web page as running on Android 4.2 or Higher.
Chinese to the effect of
Copy Code code as follows:
Warning: If your program target platform is 17 or higher, you must add @javascriptinterface annotations to the method that the Web page can invoke (this method must be public). If you don't, the Web page will not be able to access your method on the 4.2 platform.
Solving method
1. Set Targetsdkversion to 17 or higher to introduce @javascriptinterface annotation
2. Create a note interface name for @javascriptinterface and then introduce it. Note that this interface cannot be confused. This approach is not recommended, probably after 4.4 problems.
Note, create @javascriptinterface code
Copy Code code as follows:
Public @interface Javascriptinterface {
}
Code obfuscation issues
If there is no confusion in the version that runs correctly, the confusing version of the code runs incorrectly and prompts uncaught Typeerror:object [Object] has no method, which is that you did not do obfuscation exception handling. Add code like this in a confusing file
Copy Code code as follows:
-keep class Com.example.javajsinteractiondemo$jsinteration {
*;
}
All WebView methods must is called on the same thread
This problem has been found in the filter log.
Copy Code code as follows:
E/strictmode (1546): Java.lang.throwable:a WebView method is called on thread ' Javabridge '. All WebView methods must is called on the same thread. (Expected Looper looper (Main, Tid 1) {528712d4} called on Looper (Javabridge, tid 121) {52b6678c}, FYI main looper is Loo Per (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)
Java callback thread after JS call is not the main thread. such as print log verifiable
Copy Code code as follows:
Threadinfo=thread[webviewcorethread,5,main]
Solve the above exception, put the WebView operation in the main thread can be.
Copy Code code as follows:
Webview.post (New Runnable () {
@Override
public void Run () {
Webview.loadurl (Your_url).
}
});