Android 中Java和JavaScript交互入门
如何实现JavaScript 和java 交互
实现Java和js交互十分便捷。通常只需要以下几步。
- WebView开启JavaScript脚本执行
- WebView设置供JavaScript调用的交互接口。
- 客户端和网页端编写调用对方的代码。
#直接看示例代码:
java代码如下:
package com.ccb.javascript; import java.net.URISyntaxException; import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast; @TargetApi(Build.VERSION_CODES.DONUT)
public class JavaScriptDemo extends Activity { private static final String LOGTAG = "MainActivity"; @SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.javascriptdemo);
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 Intent toastMessage(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG)
.show();
Intent intent = null;
// Parse intent URI into Intent Object
int flags = 0;
boolean isIntentUri = false;
if (message.startsWith("intent:")) {
isIntentUri = true;
flags = Intent.URI_INTENT_SCHEME;
} else if (message.startsWith("#Intent;")) {
isIntentUri = true;
}
if (isIntentUri) {
try {
intent = Intent.parseUri(message, flags);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
startActivity(intent);
return intent;
} @JavascriptInterface
public void onSumResult(int result) {
Log.i(LOGTAG, "onSumResult result=" + result);
}
} }
前端网页代码
<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
<br />
<a onClick="window.control.toastMessage('#Intent;component=com.ccb.javascript/com.ccb.javascript.MainActivity;end')" href="";>调用java中的方法</a>
</html>
调用示例
js调用Java
调用格式为window.jsInterfaceName.methodName(parameterValues) 此例中我们使用的是control作为注入接口名称。
具体调用:
<a onClick="window.control.toastMessage('#Intent;component=com.ccb.javascript/com.ccb.javascript.MainActivity;end')" href="";>调用java中的方法</a>
('#Intent;component=com.ccb.javascript/com.ccb.javascript.MainActivity;end') 是传递一个打开Activity的Intent。也可以是字符串或者其他。
Java调用JS
webView调用js的基本格式为webView.loadUrl(“javascript:methodName(parameterValues)”)
调用js无参无返回值函数
String call = "javascript:sayHello()";
webView.loadUrl(call);
调用js有参无返回值函数
注意对于字符串作为参数值需要进行转义双引号。
String call = "javascript:alertMessage(\"" + "content" + "\")";
webView.loadUrl(call);
调用js有参数有返回值的函数
Android在4.4之前并没有提供直接调用js函数并获取值的方法,所以在此之前,常用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。
1.Java调用js代码
String call = "javascript:sumToJava(1,2)";
webView.loadUrl(call);
2.js函数处理,并将结果通过调用java方法返回
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
3.Java在回调方法中获取js函数返回值
@JavascriptInterface
public void onSumResult(int result) {
Log.i(LOGTAG, "onSumResult result=" + result);
}
4.4处理
Android 4.4之后使用evaluateJavascript即可。这里展示一个简单的交互示例 具有返回值的js方法
function getGreetings() {
return 1;
} java代码时用evaluateJavascript方法调用 private void testEvaluateJavascript(WebView webView) {
webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() { @Override
public void onReceiveValue(String value) {
Log.i(LOGTAG, "onReceiveValue value=" + value);
}});
} 输出结果: I/MainActivity( 1432): onReceiveValue value=1 注意 上面限定了结果返回结果为String,对于简单的类型会尝试转换成字符串返回,对于复杂的数据类型,建议以字符串形式的json返回。
evaluateJavascript方法必须在UI线程(主线程)调用,因此onReceiveValue也执行在主线程。
疑问解答
Alert无法弹出
你应该是没有设置WebChromeClient,按照以下代码设置
myWebView.setWebChromeClient(new WebChromeClient() {});
Uncaught ReferenceError: functionName is not defined
问题出现原因,网页的js代码没有加载完成,就调用了js方法。解决方法是在网页加载完成之后调用js方法
myWebView.setWebViewClient(new WebViewClient() { @Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//在这里执行你想调用的js函数
} });
Uncaught TypeError: Object [object Object] has no method
安全限制问题
如果只在4.2版本以上的机器出问题,那么就是系统处于安全限制的问题了。Android文档这样说的
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.
中文大意为
警告:如果你的程序目标平台是17或者是更高,你必须要在暴露给网页可调用的方法(这个方法必须是公开的)加上@JavascriptInterface注释。如果你不这样做的话,在4.2以以后的平台上,网页无法访问到你的方法。
解决方法
- 将targetSdkVersion设置成17或更高,引入@JavascriptInterface注释
- 自己创建一个注释接口名字为@JavascriptInterface,然后将其引入。注意这个接口不能混淆。这种方式不推荐,大概在4.4之后有问题。
注,创建@JavascriptInterface代码
public @interface JavascriptInterface { }
代码混淆问题
如果在没有混淆的版本运行正常,在混淆后的版本的代码运行错误,并提示Uncaught TypeError: Object [object Object] has no method,那就是你没有做混淆例外处理。 在混淆文件加入类似这样的代码
keepattributes *Annotation*
keepattributes JavascriptInterface
-keep class com.example.javajsinteractiondemo$JsInteration {
*;
}
All WebView methods must be called on the same thread 过滤日志曾发现过这个问题。
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)
在js调用后的Java回调线程并不是主线程。如打印日志可验证
ThreadInfo=Thread[WebViewCoreThread,5,main]
解决上述的异常,将webview操作放在主线程中即可。
webView.post(new Runnable() {
@Override
public void run() {
webView.loadUrl(YOUR_URL).
}
});
转自:http://droidyue.com/blog/2014/09/20/interaction-between-java-and-javascript-in-android/
Android 中Java和JavaScript交互入门的更多相关文章
- Android中Java和JavaScript交互
Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本.本文将介绍如何实现Java代码和Javascript代码的相互调用. 如 ...
- Android中Java与JavaScript之间交互(转)
Android代码: package com.fyfeng.testjavascript; import android.app.Activity; import android.content.In ...
- WebView上实现Java与JavaScript交互
在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用.WebView加载资源的速度并不慢,但是如果资源多了,就很慢.图片.css.js.html ...
- Android中Java与web通信
Android中Java与web通信不是新的技术了,在android公布之初就支持这样的方式,2011年開始流行,而这样的模式开发也称作Hybird模式. 这里对android中的Java与web通信 ...
- Android中Java反射技术的使用示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...
- Android中H5和Native交互的两种方式
Android中H5和Native交互的两种方式:http://www.jianshu.com/p/bcb5d8582d92 注意事项: 1.android给h5页面注入一个对象(WZApp),这个对 ...
- Android中WebView的JavaScript代码和本地代码交互的三种方式
一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...
- Android中webview跟JAVASCRIPT中的交互
在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...
- WebView中Java与JavaScript的交互
原文首发于微信公众号:jzman-blog,欢迎关注交流! Android 开发过程中 WebView 的使用比较广泛,常用来加载网页,比如使用 WebView 加载新闻页面.使用 WebView 打 ...
随机推荐
- jquery设置文本框值 与获取文本框的值
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- JSEL 表达式
JSTL标签库的使用是为类弥补html表的不足,规范自定义标签的使用而诞生的.在告别modle1模式开发应用程序后,人们开始注重软件的分层设计,不希望在jsp页面中出现java逻辑代码,同时也由于自定 ...
- linux下不重启加硬盘
linux下热加载磁盘 临时给虚拟机加了一块硬盘,增加后懒得重启,于是看了看热加载 [root@centos5 ~]# cat /proc/scsi/scsi Attached devices: Ho ...
- 第一次线上OJ水友赛
偶然的机会遇到了这个神奇的网站http://www.luogu.org/ 巧遇今天又有小比赛果断去试试,为我的蓝桥北京之旅练练手. 苦苦的在机房刷了一下午,大概做到了6点半. 最激动的是等成绩了, ...
- error C4996 The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ co ...
- Programming C#.Classes and Objects.只读字段
只读字段 当字段声明中含有 readonly 修饰符时,该声明所引入的字段为只读字段.给只读字段的直接赋值只能作为声明的组成部分出现,或在同一类中的实例构造函数或静态构造函数中出现.(在这些上下文中, ...
- CGI version1.1-第一章 介绍 (译)
CGI version1.1-第一章 介绍 1.简介 1.1 用途 CGI 是为 HTTP服务器 与 CGI脚本 在 响应客户端请求分配职责, 客户请求由url,方法与关于传输协议的附属信息, CGI ...
- Ajax中XML和JSON格式的优劣比较
刚做完一个小的使用Ajax的项目.整个小项目使用JavaScript做客户端,使用PHP做服务器端.利用xmlHttpRequest组件作为交互工具,利用XML作为数据传输的格式.做完后基本做一个简单 ...
- [转载]node.js express 4.x 安装指南,没有自动配置环境变量的问题
前几天express 推出了4.0,得知这个消息,自己尝试了一下,突然发现用以前的文档上的操作出现了各种问题.结果只能去看文档,现在在这个给大家分享下4.0版本的安装. 先说下如果需要用express ...
- visual studio 配置OpenGL环境
首先在网上下载一个GLUT工具包. glut.zip,大约一百多kb. 解压之后得到这么几个文件: 将glut.h复制到C:\Program Files (x86)\Microsoft Visual ...