`
jiaoronggui
  • 浏览: 1332223 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
博客专栏
B7c2eb31-a8ea-3973-a517-d00141f39b89
项目管理软件-redmin...
浏览量:116554
4a63e153-250f-30f6-a051-97cfc67cb3d3
IT职业规划
浏览量:199545
社区版块
存档分类
最新评论

Adnroid2.3版本模拟器在使用javascript与webkit互动时候报错为bug

阅读更多

 

 

最近在做android 的webkit与javascript的测试,发现一个严重的问题,在javascript调用android中的java方法时候,在2.3模拟器下回直接导致vm终止,错误代码如下,但是在2.2下面正常,过后尝试在4.0下的结果,此问题困扰了我2天了,找的好辛苦,特共享出来,以免走弯路:

05-01 00:18:07.523: W/dalvikvm(392): JNI WARNING: jarray 0x40543ad0 points to non-array object (Ljava/lang/String;)
05-01 00:18:07.534: I/dalvikvm(392): "WebViewCoreThread" prio=5 tid=9 NATIVE
05-01 00:18:07.534: I/dalvikvm(392):   | group="main" sCount=0 dsCount=0 obj=0x4051e820 self=0x2a5568
05-01 00:18:07.534: I/dalvikvm(392):   | sysTid=400 nice=0 sched=0/0 cgrp=default handle=2774688
05-01 00:18:07.534: I/dalvikvm(392):   | schedstat=( 1153298463 1944733293 111 )
05-01 00:18:07.553: I/dalvikvm(392):   at android.webkit.LoadListener.nativeFinished(Native Method)
05-01 00:18:07.553: I/dalvikvm(392):   at android.webkit.LoadListener.nativeFinished(Native Method)
05-01 00:18:07.563: I/dalvikvm(392):   at android.webkit.LoadListener.tearDown(LoadListener.java:1200)
05-01 00:18:07.563: I/dalvikvm(392):   at android.webkit.LoadListener.handleEndData(LoadListener.java:721)
05-01 00:18:07.563: I/dalvikvm(392):   at android.webkit.LoadListener.handleMessage(LoadListener.java:219)
05-01 00:18:07.573: I/dalvikvm(392):   at android.os.Handler.dispatchMessage(Handler.java:99)
05-01 00:18:07.573: I/dalvikvm(392):   at android.os.Looper.loop(Looper.java:123)
05-01 00:18:07.573: I/dalvikvm(392):   at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:629)
05-01 00:18:07.573: I/dalvikvm(392):   at java.lang.Thread.run(Thread.java:1019)
05-01 00:18:07.573: E/dalvikvm(392): VM aborting

 

google对于此问题的回复:

The javascript to java bridge on 2.3 Gingerbread is causing crashes.  This is 100% reproducible using the WebViewDemo application from here: http://code.google.com/p/apps-for-android/source/browse/#svn/trunk/Samples/WebViewDemo.
Note: The project file for that app is a little messed up, however, if you recreate the project, keeping the code the same, you can reproduce the error.  The sample is old, but the code should still run as none of these interfaces have been deprecated.

It is also easily reproducible by creating a simple application that creates a webview, enables javascript, adds a JS interface, then loads a script into the webview. The code for this even simpler app is attached as well as WebViewTest and a secondary Test class as the "bridge".

The demos work as expected when using 2.2

This is a serious issue as it will cause crashes for any app using the webview to do any serious work.  Thanks in advance for taking a look at this.

Attached is the output from logcat as well as the output from adb bugreport.  

 

网上有个牛人对此问题的解决:

下面开始分析这个问题

先把这个地址(http://code.google.com/p/android/issues/detail?id=12987)中,楼主的例子下载下来,安装在机器上运行。发现问题出在WebView.addJavascriptInterface方法中。只要使用Java扩展JS的API,并在脚本中调用到这些API就会出现VM崩溃。

用上面提到的方法进行跟踪,发现问题出现在

/external/webkit/WebCore/bridge/jni/jsc/JavaClassJSC.cpp中的这一句上:

if (jarray fields = (jarray)(callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;"))){

int numFields = env->GetArrayLength(fields);

...

}

callJNIMethod<jobject>方法内部出现了错误,返回的是一个jstring,在这里把它当jarray使用了。在调用env->GetArrayLength(fields)时,VM会使用/dalvik/vm/CheckJni.c中的checkArray方法对参数进行合法检验,一旦发现参数不是数组,就会调用abortMaybe()关闭VM。

 

现在问题到了(jarray)(callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;"))为什么会返回一个字符串上了。

我在测试用的APK中使用System.out.println(t)对注册扩展API时使用的Test对象进行打印,然后把callJNIMethod<jobject>返回的字符串也进行打印,发现两者相同。也就是说,无论给callJNIMethod<jobject>传入什么参数,返回结果都是序列化后的Test对象。

经过跟踪,发现callJNIMethod最终会调用/dalvik/vm/interp/Stack.c中的方法dvmCallMethodV,我在dvmCallMethodV中打印了一下method->name,发现每次callJNIMethod调用的都是toString方法,这就能解释为什么callJNIMethod返回的字符串是序列化后的Test对象的现象了。

看来,是callJNIMethod方法把繁琐的JNI调用封装在一起之后出现的问题。于是我自己写了一个方法来替换callJNIMethod<jobject>:

jobject getReturnObject(JNIEnv* env, jobject anInstance, const char* name,

const char* signature) {

jclass testClass = env->GetObjectClass(anInstance);

if (!testClass) {

LOGW("error 1");

return NULL;

}

jmethodID methodID = env->GetMethodID(testClass, name, signature);

if (!methodID) {

LOGW("error 2");

return NULL;

}

jobject result = env->CallObjectMethod(anInstance, methodID);

if (!result) {

LOGW("error 3");

return NULL;

}

return result;

}

把使用callJNIMethod<jobject>的几个地方都用getReturnObject方法进行替换,问题解决。

 

对于牛人的解决方案没有尝试过

4
0
分享到:
评论
1 楼 jiaoronggui 2013-05-01  
在模拟器4.2版本上,使用webkit与javascript也是发生错误,但是在4.1版本的android手机上没有问题,看来只是模拟器的问题,继续验证

相关推荐

    android 2.3可独立运行的模拟器

    如果我们编写了一个Android应用程序,想在一台没有Android SDK或者BUILD环境的机器显示给别人看,应该怎么办呢? 打开压缩文件,运行里面的run.bat文件,这时候就会启动android模拟器

    安卓2.3系统java模拟器直装版

    在装这个之前,我只能刷的小米2.3.7的系统,用的是那个网上下的2.3版本可用的java模拟器,就是把jbed.apk文件复制到system/app里面,libjbedvm.so文件复制到system/lib里面并改权限的那个。这个直装版出来以后,...

    android 2.3独立运行的模拟器66.1M

    如果我们编写了一个Android应用程序,想在一台没有Android SDK或者BUILD环境的机器显示给别人看,应该怎么办呢?...本资源是一个压缩包,解压之后双击运行里面的run.bat批处理文件即可启动android 2.3模拟器

    android2.3可用的java模拟器

    标题中的“android2.3可用的java模拟器”指的是在Android 2.3(Gingerbread)操作系统上能够运行的Java应用程序模拟器。这通常涉及到Java虚拟机(JVM)的实现,因为Java应用程序需要在这样的环境中才能被执行。在...

    安卓2.3系统可用的java模拟器

    在安卓系统上,尤其是针对较旧版本如安卓2.3(也称为Gingerbread),Java模拟器提供了在非Android设备或者不支持特定API级别的设备上运行Java应用的能力。这里我们主要讨论的是一个针对安卓2.3系统的Java模拟器,...

    android 2.3 sdk android-2.3-sdk

    Android 2.3 SDK,又称为Gingerbread(姜饼),是Google针对其移动操作系统Android发布的一个重要版本。这个SDK(软件开发工具包)为开发者提供了构建、测试和调试针对Android 2.3系统应用所需的工具和技术文档。...

    Android2.3应用开发实战源代码

    《Android2.3应用开发实战源代码》是林城撰写的一本书,主要针对的是Android 2.3(Gingerbread)版本的应用程序开发。这本书通过实际案例的方式,深入浅出地介绍了如何在Android 2.3平台上构建和优化应用程序。在源...

    安卓系统2.3可装的JAVA模拟器直安装版-新版

    安卓系统2.3可装的JAVA模拟器直安装版-新版,1、下载安装R.E.管理器rootexplorer(有的ROM已集成就不用了) 2、用R.E.管理器rootexplorer将下载的libjbmidp.so,libjbmidpdy.so,libjbedvm.so文件放入system\lib目录...

    多图详解Android_2.3_SDK安装教程.doc

    本文将详细介绍如何在不同操作系统上安装Android 2.3 SDK,并创建和运行Android虚拟设备(AVD)。 首先,你需要从官方渠道下载适用于你操作系统的Android 2.3 SDK。Windows用户可以下载`android-sdk_r08-windows....

    Android 2.3应用开发实战 上部分代码

    这个阶段的Android系统版本,也称为Gingerbread,是Android平台的一个重要里程碑,为开发者提供了更多的特性和优化,旨在提升用户体验和开发效率。本实战指南由林城撰写,他是一位经验丰富的Android开发者,分享了他...

    Android SDK 2.3与Eclipse最新版开发环境搭建

    在进入Android应用开发的世界之前,首先需要正确地搭建Android SDK 2.3和Eclipse的开发环境。这个过程虽然看似繁琐,但遵循正确的步骤,你可以轻松完成。以下是一份详细的搭建指南,旨在帮助你顺利开始Android编程之...

    Android模拟器Ip设置详细操作

    在Android开发过程中,Android模拟器扮演着至关重要的角色,它为开发者提供了一个可以在桌面系统上运行和测试Android应用的环境。然而,由于模拟器的网络配置与开发者的主机系统不一致,这可能导致通信问题,例如...

    Android及avd模拟器ip设置详细操作.doc

    在此,我们可以得到模拟器的 DNS 地址,默认为“10.0.2.3”,默认 IP 地址为“10.0.2.15”。 四、设置模拟器的 DNS 在 adb shell 命令行中,输入 setprop net.dns1 192.168.5.1 命令,即可把 DNS 修改成电脑 DNS。 ...

    eoeAndroid特刊第十四期:Android2.3特色讲解 pdf

    eoeAndroid特刊第十四期:Android2.3特色讲解 pdf,目录:姜饼Android2.3的新特性介绍、有关NFC技术,Android2.3的模拟器Emulator安装教程,以及一些android2.3的翻译资料和实例教程等。

    Ubuntu-32位机安装编译Android2.3源码及内核

    在本文中,我们将深入探讨如何在Ubuntu 32位系统上安装、编译Android 2.3源码以及内核,并解决编译过程中可能遇到的问题。Android 2.3,也被称为Gingerbread,是Android操作系统的一个重要版本,对开发者来说具有...

    全屏2.3_java模拟器

    标题中的“全屏2.3_java模拟器”指的是一个针对Android系统的Java模拟器,它能够让你在Android设备上运行基于Java 2.3(也称为Gingerbread)平台的应用程序。这种模拟器允许用户在全屏模式下体验原本只适用于Java...

    解决android_模拟器上网问题

    在进行Android应用开发的过程中,开发者经常需要使用Android模拟器来进行应用程序的测试与调试。然而,在某些情况下,模拟器可能会遇到无法联网的问题,这不仅影响了应用的功能测试,还可能对整个开发流程造成阻碍。...

Global site tag (gtag.js) - Google Analytics