android + javascript 相互通信实例分析
1. AndroidManifest.xml中必须使用许可 "android.permission.INTERNET", 否则会出Web page not available错误。
<uses-permission android:name="android.permission.INTERNET"/>
2. 如果访问的页面中有Javascript,则webview必须设置支持Javascript。
1 WebSettings webSetting = webview.getSettings(); 2 webSetting.setJavaScriptEnabled(true);
3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象或者覆盖webview的 setWebChromeClient
1 mWebView.setWebViewClient(new WebViewClient(){ 2 public boolean shouldOverrideUrlLoading(WebView view, String url) { 3 view.loadUrl(url); 4 return true; 5 } 6 });
1 mWebView.setWebChromeClient(new MyWebChromeClient() 2 @Override 3 public boolean onJsAlert(WebView view, String url, String message, JsResult result) { 4 Log.d(LOG_TAG, message); 5 result.confirm(); 6 return true; 7 });
4. 如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
1 public boolean onKeyDown(int keyCode, KeyEvent event) { 2 if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { 3 mWebView.goBack(); 4 return true; 5 } 6 return super.onKeyDown(keyCode, event); 7 }
5. javascript对象 与 android 对象绑定
WebView注入Java对象
对象注入即通过webview 建立 javascript对象 与 android 原生对象的绑定关系,下面代码中,obj1对象在android程序中可以操作,obj2在js程序中可以操作,两者操作的均为同一个内存对象,即可以理解为,两个绑定的对象是同一个对象在不同运行环境下的一个别名(仅个人理解,有误请大牛指正)
1 webview.getSetting().setJavaScriptEnable(true); 2 class JsObject { 3 @JavascriptInterface 4 public String toString() { return "injectedObject"; } 5 } 6 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
1 private WebView mWebView; 2 private Handler mHandler = new Handler(); 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.main); 8 mWebView = (WebView) findViewById(R.id.webview); 9 10 WebSettings webSettings = mWebView.getSettings(); 11 webSettings.setJavaScriptEnabled(true); 12 webSettings.setSavePassword(false); 13 webSettings.setSaveFormData(false); 14 webSettings.setSupportZoom(false); 15 16 mWebView.setWebChromeClient(new MyWebChromeClient()); 17 mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo"); 18 // mWebView.loadUrl("http://www.baidu.com/"); 19 mWebView.loadUrl("file:///android_asset/demo.html"); 20 } 21 22 final class DemoJavaScriptInterface { 23 DemoJavaScriptInterface() { 24 Log.i("aaaa", "create DemoJavaScriptInterface"); 25 } 26 /** 27 * This is not called on the UI thread. Post a runnable to invoke 28 * loadUrl on the UI thread. 29 */ 30 @JavascriptInterface 31 public void clickOnAndroid() { 32 mHandler.post(new Runnable() { 33 public void run() { 34 mWebView.loadUrl("javascript:wave()"); 35 } 36 }); 37 } 38 } 39 /** 40 * Provides a hook for calling "alert" from javascript. Useful for 41 * debugging your javascript. 42 */ 43 final class MyWebChromeClient extends WebChromeClient { 44 @Override 45 public boolean onJsAlert(WebView view, String url, String message, JsResult result) { 46 result.confirm(); 47 return true; 48 } 49 }
html源文件
1 <!DOCTYPE html> 2 <html> 3 <script language="javascript"> 4 /* This function is invoked by the activity */ 5 function wave() { 6 alert("1"); 7 document.getElementById("droid").src="android_waving.png"; 8 alert("2"); 9 } 10 </script> 11 <body> 12 <!-- Calls into the javascript interface for the activity --> 13 <a onClick="window.demo.clickOnAndroid()"> 14 <div style="width:80px; 15 margin:0px auto; 16 padding:10px; 17 text-align:center; 18 border:2px solid #202020;" > 19 <img id="droid" src="android_normal.png"/><br> 20 Click me! 21 </div></a> 22 </body> 23 </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
[4]. http://wenku.baidu.com/link?url=MLiRIwZQUc3-CAbSopUD-_OZ2Jt67K74RHDzqVJZCkDRnbkXp-66P9ArMbtNSy3LiPZ__nLxcQaoXP7ZImv7AujsFwBybB9wlbCJaGVTjD_
[5]. https://code.google.com/p/apps-for-android/source/browse/#git%2FSamples%2FWebViewDemo%253Fstate%253Dclosed
android + javascript 相互通信实例分析相关推荐
- Android串口通信实例分析【附源码】
Android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖- ...
- python socket通信 多进程_python实现多进程通信实例分析
操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在.那么进程之间怎么进行通信?他们之间的关联是怎样的?实现原理是什么 ...
- python安卓开发实例_python服务器与android客户端socket通信实例
本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: #server.p ...
- android 手机 与 python服务器_python服务器与android客户端socket通信实例
本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: #server.p ...
- Android中list常用方法,Android中ListActivity用法实例分析
本文实例分析了Android中ListActivity用法.分享给大家供大家参考,具体如下: 程序如下: import android.app.ListActivity; import android ...
- android中view用法,Android中ImageView用法实例分析
本文实例分析了Android中ImageView用法.分享给大家供大家参考,具体如下: 猜牌游戏大家可能以前都玩过,这里我们用这个小游戏来说明ImageView的用法. 首先,在res/drawabl ...
- android listview 分析,Android中ListView用法实例分析
本文实例分析了Android中ListView用法.分享给大家供大家参考,具体如下: 通过在Layout中添加ListView Widget可以达到在页面布局具有列表效果的交互页面.在这里通过举例来说 ...
- android 刷新view位置,Android View刷新机制实例分析
本文实例讲述了Android View刷新机制.分享给大家供大家参考,具体如下: 一.总体说明 在Android的布局体系中,父View负责刷新.布局显示子View:而当子View需要刷新时,则是通知 ...
- js php 变量声明,javascript变量声明实例分析_javascript技巧
本文实例讲述了javascript变量声明的方法.分享给大家供大家参考.具体分析如下: js中使用一个变量之前应当先声明.变量使用关键字var来声明. 如果未在var声明语句中给变量指定初始值,则该变 ...
最新文章
- Spring Boot神操作-多个数据源Service层封装
- 计算机教室开放使用计划,计算机教室实施计划方案.pdf
- c语言位运算负数的实例_一招教你学会C语言中位运算
- leetcode1442. 形成两个异或相等数组的三元组数目
- php callable 参数,php 利用反射执行callable
- [原]解决win2003 iis6 部署MVC 无法访问 403 的问题
- SpringBoot增和MongoDB实现增删改查、复合查询
- oracle lock 1,Oracle試用 DBMS_LOCK.sleep(1);權限問題
- 【15】一切都是对象
- 一文带你了解 Java 中的锁
- 思科防火墙ASA5506X总是自动重启查看crash日志
- vue实现留言板的功能_vue初探-简易留言板
- iOS苹果开发者账号(公司账号)申请流程详解
- orm之peewee
- 美术基础对学3D游戏建模重要吗?零基础如何学3D建模
- 模拟算法考试训练题和答案1
- Leetcode初级算法
- 强制用户使用定向推送功能是什么意思?整改措施请收好
- FF再次提出仲裁申请:要求解除恒大健康资产抵押权
- 冒泡排序,鸡尾酒排序,选择排序
热门文章
- 1390 游戏得分(贪心)
- 用koa开发一套内容管理系统(CMS),支持javascript和typescript双语言
- Mac环境下Docker及Splash的安装运行教程
- LEMP+memcached
- Java锁机制学习笔记——synchronized 和 Lock
- Golang访问Redis初体验
- jquery mobile 页面间的传递参数
- 深入浅出SQL Server Replication第一篇:走近Replication(上)
- JavaScript-包装对象
- Matcher 类中的group(),group(int i),groupCount()