You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android JNI调用Java动态代理方法时发生Crash的问题咨询

崩溃根因

场景1:放开代理中invoke代码时全设备崩溃

  • JNI层参数传递错误:jvalue *args = {} 实际是将args初始化为空指针,CallVoidMethodA 要求第三个参数必须是指向jvalue数组的有效指针,即使方法无入参也不能传入空指针,直接触发内存访问错误崩溃。
  • 动态代理返回值不匹配:Kotlin的lambda默认将最后一行表达式的结果作为返回值,调用method.invoke后,无返回值的void方法对应的invoke调用返回null,但部分场景下Kotlin会隐式返回Unit类型,与方法签名要求的返回值不匹配,触发ART虚拟机校验错误。

场景2:注释代理中invoke代码时仅Android 6.0(Vivo Y67等机型)崩溃

  • Android 6.0(API 23)ART虚拟机的动态代理返回值校验存在兼容缺陷:注释invoke逻辑后,InvocationHandler的lambda没有显式返回值,默认返回Kotlin的Unit对象,而Android 6.0的ART在处理JNI调用动态代理void方法的场景下,无法识别Unit作为合法返回值,定制ROM(如Vivo的老版本系统)对ART的修改进一步放大了这个问题,直接触发崩溃。
解决方案
  1. 修复JNI层参数错误:将空指针的args替换为栈上分配的空jvalue数组,修改后代码如下:
extern "C"
JNIEXPORT void JNICALL
Java_com_aprz_mytestdemo_jni_JNIInvokeProxyMethodActivity_invokeProxyMethod(JNIEnv *env,
                                                                            __unused     jobject thiz,
                                                                            jobject proxy) {
    jclass proxy_class = env->GetObjectClass(proxy);
    jmethodID test_void_method_id = env->GetMethodID(proxy_class, "testVoid", "()V");
    LOGD("jmethodId = %d", test_void_method_id == nullptr);
    // 替换为栈上分配的空数组,不要传空指针
    jvalue args[0];
    env->CallVoidMethodA(proxy, test_void_method_id, args);
}
  1. 修复动态代理返回值兼容问题:显式指定InvocationHandler的返回值,void方法统一返回null,修改后代码如下:
val proxy = Proxy.newProxyInstance(
    classLoader, arrayOf(ProxyTest::class.java)
) { _, method, args ->
    val myargs = args ?: emptyArray()
    val result = method.invoke(target, *myargs)
    // 显式处理返回值,void方法返回null,匹配所有Android版本的ART校验规则
    if (method.returnType == Void.TYPE) null else result
} as ProxyTest

如果不需要执行target的方法,也要显式返回null,避免默认返回Unit:

val proxy = Proxy.newProxyInstance(
    classLoader, arrayOf(ProxyTest::class.java)
) { _, _, _ ->
    // 无业务逻辑时也显式返回null,兼容老版本系统
    null
} as ProxyTest

内容的提问来源于stack exchange,提问作者a5right

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:15:03