android 2.3.3 网页显示问题,Android 2.3中Webkit引擎导致VM崩溃的问题

下面开始分析这个问题

先把这个地址中,楼主的例子下载下来,安装在机器上运行。发现问题出在WebView.addJavascriptInterface方法中。只要使用Java扩展JS的API,并在脚本中调用到这些API就会出现VM崩溃。

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

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

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

int numFields = env->GetArrayLength(fields);

...

}

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

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

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

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

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

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的几个地方都用getReturnObject方法进行替换,问题解决。

参考文章

在Android源码的JavaScriptCore引擎中添加LOG

android或linux调试addr2line工具锁定命令的使用

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值