The Google Android team released the Android 2.3 ("Gingerbread") SDK two days ago, to much fanfare. This has sent the tech blogging world into a publishing frenzy, as it usually does. However, a potentially disastrous bug has surfaced that could crash literally thousands of apps in the Android Market immediately after opening the app.

The problem is described succintly here:
http://code.google.com/p/android/issues/detail?id=12987
In short:
Many apps show all or part of their UI with embedded WebViews that can render HTML.
Those WebViews make use of a great feature that bridges JavaScript (in the HTML) to the native Java code that "surrounds" the WebView.
This bridge is completely broken in Android 2.3. Trying to make even a basic call breaks the WebView immediately and crashes the app.

I believe members of the Android team are aware of the problem, and from early reports, it does not affect the Nexus S (the first Android 2.3 phone). This doesn't really help those of us working against the emulator, however.

Here is a simple solution to work around this.

1.) In onCreate, check to see if the bridge is broken, and add the JavaScript interface only if not broken.

// Determine if JavaScript interface is broken.// For now, until we have further clarification from the Android team,// use version number.try {if ("2.3".equals(Build.VERSION.RELEASE)) { javascriptInterfaceBroken = true;}} catch (Exception e) {// Ignore, and assume user javascript interface is working correctly.}// Add javascript interface only if it's not brokenif (!javascriptInterfaceBroken) {webView.addJavascriptInterface(this, "jshandler");}

2.) Create a WebViewClient that passes in a new JavaScript object with the same name as your JavaScript interface object.
@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);finishLoading();// If running on 2.3, send javascript to the WebView to handle the function(s)// we used to use in the Javascript-to-Java bridge.if (javascriptInterfaceBroken) { String handleGingerbreadStupidity=    "javascript:function openQuestion(id) { window.location='http://jshandler:openQuestion:'+id; }; "  + "javascript: function handler() { this.openQuestion=openQuestion; }; "  + "javascript: var jshandler = new handler();"; view.loadUrl(handleGingerbreadStupidity);}}

NOTE: for each of the Javascript-to-Java functions that you use, you will need to add a new Javascript function and pass it in as part of the loadUrl, like the defined below.
"javascript:function openQuestion(id) { window.location='http://jshandler:openQuestion:'+id; }; "


3.) In the same WebViewClient, override the URL handling portion to handle the URLs defined in step 2. After catching the URL, parse out the function and parameters, then use reflection to actually call the method.
@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {if (javascriptInterfaceBroken) { if (url.contains("jshandler")) {  // We override URL handling to parse out the function and its parameter.  // TODO: this code can only handle a single parameter. Need to generalize it for multiple.   // Parse out the function and its parameter from the URL.  StringTokenizer st = new StringTokenizer(url, ":");  st.nextToken(); // remove the 'http:' portion  st.nextToken(); // remove the '//jshandler' portion  String function = st.nextToken();  String parameter = st.nextToken();  // Now, invoke the local function with reflection  try {   if (sMethod == null) {    sMethod = MyActivity.class.getMethod(function, new Class[] { String.class });   }   sMethod.invoke(MyActivity.this, parameter);  } catch (SecurityException e) {   e.printStackTrace();  } catch (NoSuchMethodException e) {   e.printStackTrace();  } catch (IllegalArgumentException e) {   e.printStackTrace();  } catch (IllegalAccessException e) {   e.printStackTrace();  } catch (InvocationTargetException e) {   e.printStackTrace();  } } return true;}return false;}


With this solution, you only need to make a few Android code changes and do not need to modify server output.

Comments welcome.

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. pycharm最新激活方法亲测有效可用!!!
  2. Windows系统中python的保姆级安装教程
  3. 12、华为 华三中小型企业网络架构搭建 【
  4. 一份优秀的数据分析报告该具备什么条件?
  5. php学习笔记(类的别名引入与命名冲突的解
  6. Scrapy有什么功能?架构有哪些?
  7. 给一些不懂又装逼的一些人的建议
  8. 51CTO博客意见反馈处【2021版】
  9. Oracle OCP 19c 认证1Z0-083考试题库(第8
  10. 入域时候提示无法加载指定的脱机注册表配