android + javascript 相互通信实例分析
1. AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误。
<uses-permission android:name="android.permission.INTERNET"/>
2. 如果访问的页面中有Javascript,则webview必须设置支持Javascript。
WebSettings webSetting = webview.getSettings();
webSetting.setJavaScriptEnabled(true);
3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象或者覆盖webview的 setWebChromeClient
mWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
3 view.loadUrl(url);
4 return true;
5 }
});
mWebView.setWebChromeClient(new MyWebChromeClient()
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d(LOG_TAG, message);
result.confirm();
return true;
});
4. 如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
5. javascript对象 与 android 对象绑定
WebView注入Java对象
对象注入即通过webview 建立 javascript对象 与 android 原生对象的绑定关系,下面代码中,obj1对象在android程序中可以操作,obj2在js程序中可以操作,两者操作的均为同一个内存对象,即可以理解为,两个绑定的对象是同一个对象在不同运行环境下的一个别名(仅个人理解,有误请大牛指正)
webview.getSetting().setJavaScriptEnable(true);
class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
}
webView.addJavascriptInterface(new JsObject()obj1, "injectedObject"obj2);
上面的程序建立 javascript 与android 程序的绑定关系,android 4.2 之后版本提供给js调用的函数必须带有注释语句@JavascriptInterface ,4.2版本之前向webview注入的对象所暴露的接口不是必须带有@JavascriptInterface注释语句(需要注意,android adt,eclipse生成的工程,低版本中会自动带有 anotations.jar,支持@JavascriptInterface, 而高版本中工程中,不会自动带有anotations.jar包,所以要加入注释语句@JavascriptInterface,首先要自己手动加入anotations.jar包,不要忘记import 哦!本人就犯过这么低级的错误哦)
官方文档解释是因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加 @JavascriptInterface 注释,这样,这个Java对象的fields 将不允许被JS访问。[2]
注:如果将targetSdkVersion 设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报如下输出:
Console: Uncaught TypeError: Object [object Object] has no method 'toString'
(需要特注意的一点,这里的限制是通过 targetSdkVersion 为标准,即如果工程采用了android sdk的版本是4.2以上,但是 targetSdkVersion 的版本在17之下,那么该状态下生成的应用,不过报错,如果targetSdkVersion 设置为>=17 就需要特别主意,要加上 @JavascriptInterface注释语句了, 所有建议在各种版本下都采用@JavascriptInterface注释,就万无一失了)
6. 在做webview开发是经常会加载本机的html文件如下:
file:///android_asset/teste.html 加载项目assets下的文件teste.html
file:///sdcard/index.html 加载sdcard下的index.html文件
源代码:
android
private WebView mWebView;
private Handler mHandler = new Handler(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setSupportZoom(false); mWebView.setWebChromeClient(new MyWebChromeClient());
mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
// mWebView.loadUrl("http://www.baidu.com/");
mWebView.loadUrl("file:///android_asset/demo.html");
} final class DemoJavaScriptInterface {
DemoJavaScriptInterface() {
Log.i("aaaa", "create DemoJavaScriptInterface");
}
/**
* This is not called on the UI thread. Post a runnable to invoke
* loadUrl on the UI thread.
*/
@JavascriptInterface
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
mWebView.loadUrl("javascript:wave()");
}
});
}
}
/**
* Provides a hook for calling "alert" from javascript. Useful for
* debugging your javascript.
*/
final class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}
}
html源文件
<!DOCTYPE html>
<html>
<script language="javascript">
/* This function is invoked by the activity */
function wave() {
alert("1");
document.getElementById("droid").src="android_waving.png";
alert("2");
}
</script>
<body>
<!-- Calls into the javascript interface for the activity -->
<a onClick="window.demo.clickOnAndroid()">
<div style="width:80px;
margin:0px auto;
padding:10px;
text-align:center;
border:2px solid #202020;" >
<img id="droid" src="android_normal.png"/><br>
Click me!
</div></a>
</body>
</html>
参考文档:
[1]. WebView注入Java对象注意事项 参考:http://blog.csdn.net/zgjxwl/article/details/9627685
[2]. Android WebView的Js对象注入漏洞解决方案 http://my.oschina.net/u/1402271/blog/306364
[3]. https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface
android + javascript 相互通信实例分析的更多相关文章
- android和javascript之间相互通信实例分析
1. AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误 ...
- AS3和js相互通信要点分析
目标:在html页面里可以使用事件来影响到swf文件的内容,swf文件也可以影响html里js代码的内容 一.新建flash文件,用Flash CC试用版新建一个TextArea.fla的源文件,不添 ...
- Android中AIDL通信机制分析
一.背景 ·1.AIDL出现的原因 在android系统中,每一个程序都是运行在自己的进程中,进程之间无法进行通讯,为了在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需 ...
- python多进程通信实例分析
操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在.那么进程之间怎么进行通信?他们之间的关联是怎样的?实现原理是什么 ...
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- Hybrid App开发模式中, IOS/Android 和 JavaScript相互调用方式
IOS:Objective-C 和 JavaScript 的相互调用 iOS7以前,iOS SDK 并没有原生提供 js 调用 native 代码的 API.但是 UIWebView 的一个 dele ...
- Python使用Ctypes与C/C++ DLL文件通信过程介绍及实例分析
项目中可能会经常用到第三方库,主要是出于程序效率考虑和节约开发时间避免重复造轮子.无论第三方库开源与否,编程语言是否与当前项目一致,我们最终的目的是在当前编程环境中调用库中的方法并得到结果或者借助库中 ...
- Android Touch事件原理加实例分析
Android中有各种各样的事件,以响应用户的操作.这些事件可以分为按键事件和触屏事件.而Touch事件是触屏事件的基础事件,在进行Android开发时经常会用到,所以非常有必要深入理解它的原理机制. ...
- android与javascript相互调用
下面这一节来介绍android和javascript是怎么相互调用的,这样我们的UI界面设计起来就简单多了,而且UI设计起来也可以跨平台.现在有好多web app前台框架了,比如sencha和jque ...
随机推荐
- 228. Summary Ranges
Given a sorted integer array without duplicates, return the summary of its ranges. For example, give ...
- java运用Comparator为对象排序
要排序的类需要实现Comparator接口,重写compare方法: user类及实现接口的内部类: package test; import java.util.Comparator; public ...
- window下部署php_redis扩展
关于redis的一些特性就不多说了,可以到这里去了解,or click me. 另外,给出一个redis中文API,点我. 首先要下载一个redis软件,可以到官网下载. 注意:官网提供的版本比较高级 ...
- linux网络不同的解决办法
贯标防火墙,iptables 注释掉/etc/hosts的localhost的ipv6地址映射
- .net EntityFramework用法探索系列 1
EntityFramework用法探索系列 (一)DatabaseFirst (二)CodeFirst (三)CodeFirst流畅API (四)Repository和UnitOfWork (五)引入 ...
- JMS的常用方法
import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; impor ...
- python(15)提取字符串中的数字
python 提取一段字符串中去数字 ss = “123ab45” 方法一:filter filter(str.isdigit, ss) 别处copy的filter的用法: # one>> ...
- linux下shell脚本学习
在Linux系统中,虽然有各种各样的图形化接口工具,但是sell仍然是一个非常灵活的工具.Shell不仅仅是命令的收集,而且是一门非常棒的编程语言.您可以通过使用shell使大量的任务自动化,shel ...
- ajax 如何实现页面跳转
老师,您好.jquery的ajax如何实现页面跳转?例如:登陆页面属于用户名和密码后,点击登陆,验证用户名和密码,正确后,跳转到其他页面.能否给个例子. 下面列了五个例子来详细说明,这几个例子的主要功 ...
- ubuntu 14.10 安装 zabbix
在ubuntu 14.10 上部署 zabbix 2.x 基本软件包安装 既然是ubuntu系统,当然要用好apt-get神器. 参考教程 URL:http://blog.csdn.net/cloud ...