转自:http://blog.csdn.net/span76/article/details/9065941

WebView 常识

使用 Alert  提供消息

我在页面经常用 Alert 提供消息,  但 Android 需要你编写 MyWebChromeClient

mWebView.setWebChromeClient(new MyWebChromeClient());

  1. final class MyWebChromeClient extends WebChromeClient {
  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. }
  8. }

当然类似还有 onJsConfirm , onJsPrompt 等, ref: http://developer.android.com/reference/android/webkit/WebChromeClient.html

Android 与 JavaScript  的交互

WebSettings webSettings = mWebView.getSettings(); 
        webSettings.setJavaScriptEnabled(true);  
        mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");

  1. final class DemoJavaScriptInterface {
  2. public void clickOnAndroid() {
  3. mHandler.post(new Runnable() {
  4. public void run() {
  5. mWebView.loadUrl("javascript:wave()");
  6. }
  7. });
  8. }
  9. }
  1. <html>
  2. <script language="javascript">
  3. /* This function is invoked by the activity */
  4. function wave() {
  5. alert("1");
  6. document.getElementById("droid").src="android_waving.png";
  7. alert("2");
  8. }
  9. </script>
  10. <body>
  11. <!-- Calls into the javascript interface for the activity -->
  12. <a onClick="window.demo.clickOnAndroid()"><div style="width:80px;
  13. margin:0px auto;
  14. padding:10px;
  15. text-align:center;
  16. border:2px solid #202020;" >
  17. <img id="droid" src="android_normal.png"/><br>
  18. Click me!
  19. </div></a>
  20. </body>
  21. </html>

程序详细内容 ref: http://bolutes.iteye.com/blog/1320344

实战

最近跑 0xbench 中 Android WebView 测试 sunspider 测试, 发现 sunspider 跑一阵就停留在白色屏幕,不知为何?

打开 0xbench/src/org/zeroxlab/benchmark/TesterJavascript.java 看了看, 这个testcase比较简单

  1. public class TesterJavascript extends Tester {
  2. protected WebView mWebView;
  3. protected WebSettings mSettings;
  4. private double mTotalTime = 0.0;
  5. private String mResult = "";
  6. private String mFormattedResult = "";
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.javascript);
  11. mWebView = (WebView) findViewById(R.id.web);
  12. mSettings = mWebView.getSettings();
  13. mSettings.setJavaScriptEnabled(true);
  14. mWebView.addJavascriptInterface(new MsgCallback(), "ANDROID_OBJ");
  15. startTester();
  16. }
  17. @Override
  18. public void onResume() {
  19. super.onResume();
  20. }
  21. @Override
  22. protected String getTag() {
  23. return "JavaScript";
  24. }
  25. @Override
  26. protected int sleepBeforeStart() {
  27. return 1000;
  28. }
  29. @Override
  30. protected int sleepBetweenRound() {
  31. return 1000;
  32. }
  33. @Override
  34. protected void oneRound() {
  35. mWebView.loadUrl("file:///android_asset/driver.html");
  36. }
  37. @Override
  38. protected boolean saveResult(Intent intent) {
  39. intent.putExtra(CaseJavascript.SUNSPIDER_RESULT, mResult);
  40. intent.putExtra(CaseJavascript.SUNSPIDER_FORMATTED_RESULT, mFormattedResult);
  41. intent.putExtra(CaseJavascript.SUNSPIDER_TOTAL, mTotalTime);
  42. return true;
  43. }
  44. class MsgCallback {
  45. public void finish(String result, String formatted_result) {
  46. mResult = result;
  47. mFormattedResult = formatted_result;
  48. decreaseCounter();
  49. }
  50. }
  51. }

就是打开 driver.html, 让其自动运行其中的 JS, 而后通过 JS callback MsgCallback.finish 把测试结果数据返回

在看看 0xbench/assets/driver.html 的代码段, 其中

  1. function finish()
  2. {
  3. initialize();
  4. computeItemTotals();
  5. computeTotals();
  6. computeMeans();
  7. computeStdDevs();
  8. computeStdErrors();
  9. var formattedOutput = getOutputForUpload();
  10. var finalOutput = getOutput();
  11. window.ANDROID_OBJ.finish(finalOutput, formattedOutput);
  12. }

其中: window.ANDROID_OBJ.finish(finalOutput, formattedOutput); 正是回调, ANDROID_OBJ 是 inject 的 obj 就是 MsgCallback 的实例

让 html 调试方便

每次都改 assets中的 html, 再安装调试是痛苦的

在 TesterJavascript.java 把 mWebView.loadUrl("file:///android_asset/driver.html"); 改为

mWebView.loadUrl("file:///sdcard/sunspider/driver.html");

再把 asset 中的中文件 copy 到 sdcard/sunspider/ 下面

以后每次调试只需要改写下 html ,而后可直接重新运行

定位问题:
  1. window.alert("before calling finish")
  2. window.ANDROID_OBJ.finish(finalOutput, formattedOutput)
  3. window.alert("after calling finish")

发现只弹出第一个对话框, 看来回调不成功, 后来又看了 log, 发现与设想一致

E/Web Console(  343): Uncaught TypeError: Object org.zeroxlab.zeroxbenchmark.TesterJavascript$MsgCallback@a5972b68 has no method 'finish' at file ...

解决:
根据关键字google 了一些, 发现问题很可能是 proguard 把程序优化了(正如下面这篇文章提到的) , 因为 eclipse 编译的 0xbench 能在系统上跑, 而出问题的 0xbench 不是在 eclipse 中编译出来的

http://stackoverflow.com/questions/7424510/uncaught-typeerror-when-using-a-javascriptinterface

于是又回到那个简单的webviewdemo 程序, 检查build 系统是否出问题

运行以前那个小程序, 发现同样问题, 再用 jd-gui 查看build系统 progruad刚处理过 proguard.classes.jar 果然方法被过滤掉了, 而proguard 处理之前的 jar 是有的

在 Android.mk 中加入

LOCAL_PROGUARD_FLAG_FILES := proguard.cfg

在 Android.mk 同级目录中建立 proguard.cfg 内容是:

  1. -keepclassmembers class com.pnp.webview.WebViewDemo.DemoJavaScriptInterface {
  2. <methods>;
  3. }

但编译过程中, proguard 不认

Proguard 编译命令是

  1. external/proguard/bin/proguard.sh -injars out/target/common/obj/APPS/WebView_intermediates/classes.jar -outjars out/target/common/obj/APPS/WebView_intermediates/proguard.classes.jar -libraryjars out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar -include build/core/proguard.flags -forceprocessing -printmapping out/target/common/obj/APPS/WebView_intermediates/proguard_dictionary -include out/target/common/obj/APPS/WebView_intermediates/proguard_options   -include webview/proguard.cfg

报错是

  1. Reading program jar [/home/payne/2jb/out/target/common/obj/APPS/WebView_intermediates/classes.jar]
  2. Reading library jar [/home/payne/2jb/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar]
  3. Note: the configuration refers to the unknown class 'com.pnp.webview.WebViewDemo.DemoJavaScriptInterface'
  4. Note: there were 1 references to unknown classes.
  5. You should check your configuration for typos.

( 后来查明查明应该用)

  1. -keepclassmembers class com.pnp.webview.WebViewDemo$DemoJavaScriptInterface {
  2. <methods>;
  3. }

另外还可以用

  1. -keep class com.pnp.webview.JavascriptCallback
  2. -keep class * implements com.pnp.webview.JavascriptCallback
  3. -keepclassmembers class * implements com.pnp.webview.JavascriptCallback {
  4. <methods>;
  5. }

用jd-gui 打开, 却找不到相应的类

终于想到了, jd-gui 也有可能出问题. 所以不管 jd-gui 了, 直接安装程序运行, 得到了想要的结果.

【转】 Android经验: proguard 阻碍 webview 正常工作的更多相关文章

  1. Android开发必知--WebView加载html5实现炫酷引导页面

    大多数人都知道,一个APP的引导页面还是挺重要的,不过要想通过原生的Android代码做出一个非常炫酷的引导页相对还是比较复杂的,正巧html5在制作炫酷动画网页方面比较给力,我们不妨先利用html5 ...

  2. Chromium Graphics: Android L平台上WebView的变化及其对浏览器厂商的影响分析

    原创文章.转载请以链接形式注明原始出处为http://blog.csdn.net/hongbomin/article/details/40799167. 摘要:Google近期公布的Android L ...

  3. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  4. Android混合开发之WebView使用总结

    前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结. 混合开发相关博客: Android混合开发之WebView使用总结 Android混合开 ...

  5. Android安全开发之WebView中的地雷

    Android安全开发之WebView中的地雷 0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者 ...

  6. Android控件之WebView

    如何在Android应用中打开Web网站呢?谷歌为我们提供了解决方案,现在就让我们一起看一下WebView控件吧. 为了方便总结,就以实现下面这个效果为主线,进行总结: 首先我们先看一下它的布局文件吧 ...

  7. android基础开发之WebView

    WebView 是android平台沟通 http & H5 页面的桥梁. 但是google对这块的表述不是很清晰,而且SDK里面基本看不到源码,只有一个接口而已. 传送:http://dev ...

  8. android软件开发之webView.addJavascriptInterface循环渐进【二】

    本篇文章由:http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gra ...

  9. android软件开发之webView.addJavascriptInterface循环渐进【一】

    本篇文章由:http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gra ...

随机推荐

  1. 【ASP.NET基础】客户端、服务器端的数据验证 + CKEditer

    1, 客户端 用Javascript进行验证,直接提示用户输入的数据是否符合规范,是否合法. 这样体验行比较好,客户端立即就可以得到反馈,而且减少了服务器端的数据交互. 这样前端数据验证并不是很安全, ...

  2. a标签中使用img后的高度多了4px

    前两天,在做一个网站的时候,发现a标签中使用img后的高度多了4px,各种纠结. 最后,仔细分析,终于找到原因了,因为img是行内元素,默认display: inline; 它与文本的默认行为类似,下 ...

  3. C# 简单邮件群发通用类

    public static class Email { /// <summary> /// 发件人 /// </summary> public static string ma ...

  4. EL表达式隐含对象

    EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据. 语法:${隐式对象名称}  :获得对象的引用 <%@ page lang ...

  5. lua技巧分享之保护执行

    我们在c#/c++里为了防止调用出现异常的时候程序可以正常的执行,经常使用try{}catch{}的结构, 那么,语言简单的lua是怎么做到的呢?答案就在pcall 先简单的介绍一下这个函数: --尝 ...

  6. Cisco基本命令配置

    实验一 路由器的基本命令操作 1 实验目标 ü 熟悉路由器的命令行操作 ü 能够使用命令行帮助 ü 能够查看路由器接口信息 ü 能够产看路由器配置信息 ü 能够配置以太网接口 ü 能够配置广域网接口 ...

  7. 【转义字符】HTML 字符实体&lt; &gt: &amp;等

    在开发中遇到javascript从后台获取的url 会被转义,如:http://localhost:8080/Home/Index?a=14&b=15&c=123,想把它转成http: ...

  8. List.Select按字符串选择属性

    不知道大家有没有遇到这样的情况:List使用Lambda表达式的时候,想要选择项的某个属性列. 例如,选择编号ID: var idList=list.Select(o=>o.ID).ToList ...

  9. 三款精美的html5及css3的源码插件

    1.HTML5 3D爱心动画 晚来的七夕礼物 七夕情人节刚过,今天小编却在国外的网站上看到一个利用HTML5和CSS3制作的3D爱心动画,莫非老外也过七夕?当然小编还是将这款HTML5 3D爱心动画收 ...

  10. hdu 2544 最短路 Dijkstra

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 题目分析:比较简单的最短路算法应用.题目告知起点与终点的位置,以及各路口之间路径到达所需的时间, ...