首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

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

2013-07-01 
Adnroid2.3版本模拟器在使用javascript与webkit互动时候报错为bug??最近在做android 的webkit与javascript

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 NATIVE05-01 00:18:07.534: I/dalvikvm(392):   | group="main" sCount=0 dsCount=0 obj=0x4051e820 self=0x2a556805-01 00:18:07.534: I/dalvikvm(392):   | sysTid=400 nice=0 sched=0/0 cgrp=default handle=277468805-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.2This 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方法进行替换,问题解决。

?

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

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

热点排行