Android WebView is a very powerful control, this article mainly for its simple use and the author in the use of the problems encountered in doing some summary.
This article references the blog post:http://blog.csdn.net/zgjxwl/article/details/9627685
First, Java and JavaScript interaction in WebView
1. This is the injected interface class to interact with JS:
Public Final class javascriptinteerface{ @JavascriptInterface publicvoid Test (String teststr { Toast.maketext (Getapplicationcontext (), Teststr, Toast.length_long). Show (); @JavascriptInterface publicvoid test1 () {
//Call JS code Webview.loadurl ("Javascript:testjavacall (' This is the Java JS method ')");} }
2. This is the code of the interaction, where the window.testObject.test in data (' This is JS out of Java's Test method ') is the code that calls Java
Webview.getsettings (). setjavascriptenabled (true); Webview.addjavascriptinterface (NewJavascriptinteerface (), "Testobject");//the HTML code of the testString data = ";//if it is a webpage, use the Loadurl (URL) method directlyWebview.loaddatawithbaseurl (NULL, data, "text/html", "Utf-8",NULL);
second, when used to meet issues with Android version compatibility
WebView There is a compatibility issue that is caused by an Android system version upgrade. This paper mainly discusses the interaction of Java and JS. There is a difference between the 4.2 version and the 4.2 version (included) after the Access JS.
Prior to this, I used the following injection interface classes:
Public Final class javascriptinteerface{ publicvoid Test () { "This is the test method for Java code", Toast.length_long). Show (); }}
Called as:
Webview.getsettings (). setjavascriptenabled (true); Webview.addjavascriptinterface (New javascriptinteerface (), "Testobject");
According to the above method, the operation on my phone (Android system version 4.4.2) is not responding, the following error is displayed when viewing log:
E/web console:uncaught Typeerror:object [Object Object] have no method ' test ' at about:blank:1
cause: Because this interface allows JavaScript to control the host application, this is a powerful feature, but at the same time, there is a significant security risk before the 4.2 version because JavaScript can use reflection to access the public of the Java object injected WebView Fields, using this method in a WebView containing untrusted content, would allow an attacker to tamper with the host application and execute Java code with the privileges of the host application. Therefore, after 4.2, any interface for JS exposure needs to add @JavascriptInterface comments, so that the Java object's fields will not be allowed to be accessed by JS.
The official website for this question is probably described as follows:
Public void addjavascriptinterface (Object object, String name) Added in API Level 1
Injects the supplied Java object into this WebView. The object is injected into the JavaScript context of the main frame, using the supplied name. This allows the Java object ' s methods-to is accessed from JavaScript. For applications targeted to API level JELLY_BEAN_MR1
and above, only public methods that is annotated with JavascriptInterface
can is accessed From JavaScript. For applications targeted to API level JELLY_BEAN
or below, all public methods (including the inherited ones) can is accessed, See the important security note below for implications.
Note that injected objects won't appear in JavaScript until the page is next (re) loaded. For example:
Class Jsobject {
@JavascriptInterface
Public StringTostring() { Return "Injectedobject"; }
}
webview. (new jsobject< Span class= "pun" > (), webview. Loaddata ( "" , "Text/html" , null); webview. Loadurl
IMPORTANT:
- This method can is used to allow JavaScript to control the host application. This was a powerful feature, but also presents a security risk for apps targeting
JELLY_BEAN
or earlier. Apps that target a version later than is JELLY_BEAN
still vulnerable if the app runs on a device running Android earlier than 4.2. The most secure-to-use, the-method is-to-target and to-ensure the method is called if running on and JELLY_BEAN_MR1
Roid 4.2 or later. With these older versions, JavaScript could the use of reflection to access a injected object ' s public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using the This method in a WebView which could contain untrusted content.
- JavaScript interacts with Java object in a private, background thread of this WebView. Care was therefore required to maintain thread safety.
- The Java object ' s fields is not accessible.
- For applications targeted to API level
LOLLIPOP
and above, methods of injected Java objects is enumerable from JavaScript.
So, to solve this problem: Just add this @JavascriptInterface to each of the Java interfaces that each JavaScript calls . For example, my previous code changed to
Public Final class javascriptinteerface{ @JavascriptInterface publicvoid Test () { " This is the Java code test method ", Toast.length_long). Show (); }}
At this point, the problem has been resolved. In addition to this problem, in doing iOS and Android at the same time with the same HTML5 JS interaction, also encountered a problem, mainly to inject JS object is not the same result, this solution is best in iOS to HTML dynamically injected JS code, or in JS to determine the client use of the device, There is not much to explain here.
Java and JavaScript interaction in Android