Android调用File.listFiles报错JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illeg

在调试Android 5.1 ART环境下文件管理应用时,遇到File.listFiles()调用引发的JNI错误,错误原因是文件名非UTF-8编码。通过参考相关文章,尝试在AndroidManifest.xml中设置android:debuggable="false",但导致应用崩溃。最终解决方案是使用签名文件打包发布版本,问题得到解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作环境(蓝色粗体字为特别注意内容)
1,系统环境:Win7 Ultimate sp1、Eclipse+ ADTv22.3.0-887826
2、硬件环境:Android 5.1 ART
3、参考文献:https://www.jianshu.com/p/7dd63f1e5333、https://blog.youkuaiyun.com/u013174667/article/details/80773700、https://blog.youkuaiyun.com/u010637392/article/details/77164745

今天在修改一个老工程,这个是一个类似文件管理的项目,在调试过程中发现了奇怪的报错,内容如下:

02-18 13:46:46.826: E/ActivityThread(2177): Failed to find provider info for childmode
02-18 13:46:46.906: E/HAL(334): hw_get_module_by_class: lib loaded: /system/lib64/hw/gralloc.msm8916.so
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]     string: '相关?'
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]     in call to NewStringUTF
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]     from java.lang.String[] java.io.File.listImpl(java.lang.String)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   | group="main" sCount=0 dsCount=0 obj=0x74f08fa8 self=0x55b5459b50
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   | sysTid=12762 nice=0 cgrp=default sched=0/0 handle=0x7f96a5fea0
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   | state=R schedstat=( 247491771 9657548 89 ) utm=21 stm=3 core=2 HZ=100
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   | stack=0x7fc224f000-0x7fc2251000 stackSize=8MB
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   | held mutexes= "mutator lock"(shared held)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   native: #00 pc 00003a34  /system/lib64/libbacktrace_libc++.so (Backtrace::Unwind(unsigned long, ucontext*)+28)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   native: #01 pc 00000027  ???
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at java.io.File.listImpl(Native method)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at java.io.File.list(File.java:745)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at java.io.File.listFiles(File.java:787)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at com.ktls.fileinfo.FileInfoMainActivity.b(FileInfoMainActivity.java:364)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at com.ktls.fileinfo.FileInfoMainActivity.a(FileInfoMainActivity.java:291)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at com.ktls.fileinfo.FileInfoMainActivity.onCreate(FileInfoMainActivity.java:682)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.Activity.performCreate(Activity.java:6102)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2410)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.ActivityThread.access$1200(ActivityThread.java:165)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.os.Handler.dispatchMessage(Handler.java:102)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.os.Looper.loop(Looper.java:135)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at android.app.ActivityThread.main(ActivityThread.java:5669)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at java.lang.reflect.Method.invoke!(Native method)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at java.lang.reflect.Method.invoke(Method.java:372)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
02-18 13:46:47.216: A/art(12762): art/runtime/check_jni.cc:65] 
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] Runtime aborting...
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] Aborting thread:
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] "main" prio=5 tid=1 Native
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | group="" sCount=0 dsCount=0 obj=0x74f08fa8 self=0x55b5459b50
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | sysTid=12762 nice=0 cgrp=default sched=0/0 handle=0x7f96a5fea0
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | state=R schedstat=( 277386927 9749371 92 ) utm=22 stm=5 core=2 HZ=100
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | stack=0x7fc224f000-0x7fc2251000 stackSize=8MB
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | held mutexes= "abort lock" "mutator lock"(shared held)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   native: #00 pc 00003a34  /system/lib64/libbacktrace_libc++.so (Backtrace::Unwind(unsigned long, ucontext*)+28)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   native: #01 pc 00000027  ???
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.listImpl(Native method)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.list(File.java:745)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.listFiles(File.java:787)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.b(FileInfoMainActivity.java:364)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.a(FileInfoMainActivity.java:291)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.onCreate(FileInfoMainActivity.java:682)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.Activity.performCreate(Activity.java:6102)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2410)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.access$1200(ActivityThread.java:165)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.os.Handler.dispatchMessage(Handler.java:102)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.os.Looper.loop(Looper.java:135)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.main(ActivityThread.java:5669)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.lang.reflect.Method.invoke!(Native method)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.lang.reflect.Method.invoke(Method.java:372)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] Dumping all threads without appropriate locks held: thread list lock mutator lock
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] All threads:
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] DALVIK THREADS (17):
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] "main" prio=5 tid=1 Native
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | group="" sCount=0 dsCount=0 obj=0x74f08fa8 self=0x55b5459b50
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | sysTid=12762 nice=0 cgrp=default sched=0/0 handle=0x7f96a5fea0
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | state=R schedstat=( 307315052 9802288 93 ) utm=24 stm=6 core=2 HZ=100
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | stack=0x7fc224f000-0x7fc2251000 stackSize=8MB
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   | held mutexes= "abort lock"
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   native: #00 pc 00003a34  /system/lib64/libbacktrace_libc++.so (Backtrace::Unwind(unsigned long, ucontext*)+28)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   native: #01 pc 00000027  ???
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.listImpl(Native method)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.list(File.java:745)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.io.File.listFiles(File.java:787)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.b(FileInfoMainActivity.java:364)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.a(FileInfoMainActivity.java:291)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.ktls.fileinfo.FileInfoMainActivity.onCreate(FileInfoMainActivity.java:682)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.Activity.performCreate(Activity.java:6102)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2410)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2519)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.access$1200(ActivityThread.java:165)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.os.Handler.dispatchMessage(Handler.java:102)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.os.Looper.loop(Looper.java:135)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at android.app.ActivityThread.main(ActivityThread.java:5669)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.lang.reflect.Method.invoke!(Native method)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at java.lang.reflect.Method.invoke(Method.java:372)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] 
02-18 13:46:47.416: A/art(12762): art/runtime/runtime.cc:289] "Heap thread pool worker thread 1" prio=5 tid=2 Native (still starting up)
02-18
<think>好的,我现在需要解决用户提到的JNI报错问题:“JNI DETECTED ERROR IN APPLICATION: can't call java.io.InputStream in call to CallObjectMethodV”。首先,我得理解这个错误的具体原因和可能的情况。 用户可能在JNI代码中调用了某个Java对象的CallObjectMethodV方法,但参数类型不匹配。错误信息指出无法调用java.io.InputStream,可能是在调用某个返回InputStream的方法时出了问题。常见的情况可能有以下几种: 1. **方法签名错误**:JNI调用方法时,需要准确的方法签名。如果方法签名与实际Java方法不匹配,JNI会找不到正确的方法,导致调用失败。比如,假设Java方法返回的是InputStream,但签名写成了其他类型,如Ljava/lang/Object;,或者参数类型不正确,就会出问题。 2. **对象引用问题**:可能调用方法的对象不是正确的Java实例。比如,如果获取实例的方法有误,或者对象已经被回收,导致调用时对象不存在,进而引发错误。 3. **JNIEnv的使用错误**:在多线程环境下,JNIEnv是每个线程独有的,如果在错误的线程中使用,或者JNIEnv指针被错误使用,可能导致问题。 接下来,我需要逐步分析可能的解决步骤。首先,用户应该检查他们调用的方法签名是否正确。可以使用javap -s命令获取准确的签名。例如,假设Java类中有一个方法public InputStream getInputStream(String path),其签名应该是类似(Ljava/lang/String;)Ljava/io/InputStream;。用户需要确保在JNI代码中使用的是这个正确的签名。 然后,检查在JNI中是否正确获取了方法ID。例如,调用GetMethodID时,传入的类对象、方法名和签名是否正确。如果方法名拼写错误,或者类名不正确(如使用了错误的包路径),GetMethodID会返回NULL,这时候继续调用CallObjectMethodV就会导致崩溃。 另外,需要确认调用CallObjectMethodV时传入的对象是否是该方法所属的实例。例如,如果调用的是一个实例方法,必须确保传入的jobject参数是该类的有效实例;如果是静态方法,则需要使用CallStaticObjectMethod,并且传入jclass而不是jobject。 还有可能是在调用方法时参数不匹配,例如方法需要参数但未正确传入,或者参数类型不对。例如,方法需要一个jstring参数,但实际传入的是其他类型,或者没有正确转换本地字符串到jstring。 另外,考虑JNI异常处理的问题。在调用JNI方法时,如果有异常抛出,应该检查异常并处理,否则后续的JNI调用可能会导致未定义行为。用户可以在调用JNI方法后使用ExceptionCheck或ExceptionOccurred来检查是否有异常发生,并及时处理。 可能还需要检查是否在正确的上下文中使用JNIEnv。比如,在异步回调或者不同线程中调用JNI时,需要确保每个线程都正确获取了JNIEnv指针,否则会导致错误。 总结一下,解决步骤可能包括: 1. 检查方法签名是否正确,使用javap工具确认。 2. 确保正确获取方法ID,并且方法ID不为NULL。 3. 确认调用方法的对象实例是否正确有效。 4. 检查参数类型和数量是否与方法签名匹配。 5. 处理JNI异常,避免异常未捕获导致后续错误。 6. 确保在多线程环境下正确使用JNIEnv。 此外,用户可能需要注意内存管理问题,比如局部引用是否溢出,或者没有正确释放局部引用导致的内存泄漏,这些也可能间接引发问题。不过这个错误更可能直接与方法调用相关。 最后,建议用户提供一个代码片段,这样能更具体地分析问题所在。例如,展示JNI中获取方法ID和调用CallObjectMethodV的部分代码,以便检查是否有明显的错误。</think>--- ### 逐步解析:`JNI DETECTED ERROR IN APPLICATION: can't call java.io.InputStream in call to CallObjectMethodV` 这个错误通常是由于 **JNI代码调用Java方法时,方法签名不匹配** 或 **对象类型错误** 导致的。以下是具体原因和解决方案: --- #### 1. **检查方法签名是否正确** - **问题根源**:JNI调用Java方法时,需通过方法签名(Method Signature)匹配目标方法。如果签名错误,JNI调用错误的方法,导致类型不兼容。 - **解决方法**: 1. 使用 `javap -s` 获取方法的准确签名。例如,对于以下Java方法: ```java public class MyClass { public InputStream getInputStream(String path) { ... } } ``` 执行 `javap -s MyClass`,输出结果中会显示签名: ``` descriptor: (Ljava/lang/String;)Ljava/io/InputStream; ``` 2.JNI代码中使用此签名: ```c jmethodID methodID = env->GetMethodID( cls, "getInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;" ); ``` --- #### 2. **确认方法ID获取成功** - **问题根源**:如果 `GetMethodID()` 返回 `NULL`,调用 `CallObjectMethodV()` 会崩溃。 - **解决方法**: - 检查方法名和签名是否与Java代码完全一致(包括大小写)。 - 确保 `jclass` 参数 `cls` 是目标类的正确引用(例如通过 `FindClass("com/example/MyClass")` 获取)。 --- #### 3. **验证对象实例有效性** - **问题根源**:如果调用方法的Java对象(`jobject`)无效(如已被释放或未正确初始化),会导致错误。 - **解决方法**: - 确保 `jobject` 是通过合法途径获得的实例(如构造函数调用或其他方法返回)。 - 使用 `env->IsSameObject(obj, NULL)` 检查对象是否为 `null`。 --- #### 4. **参数类型匹配** - **问题根源**:调用方法时传入的参数类型与签名不匹配,例如: - Java方法需要一个 `String`,但JNI传入了一个 `jint`。 - 参数数量错误(如方法需要1个参数,但传入了0个)。 - **解决方法**: - 对照签名检查参数类型和数量: ```c // 正确示例:传入一个jstring参数 jstring path = env->NewStringUTF("/data/file.txt"); jobject inputStream = env->CallObjectMethod( obj, methodID, path ); ``` --- #### 5. **处理JNI异常** - **问题根源**:Java代码可能抛出未处理的异常,导致后续JNI调用失败。 - **解决方法**: - 在关键JNI操作后检查异常: ```c if (env->ExceptionCheck()) { env->ExceptionDescribe(); // 打印异常信息 env->ExceptionClear(); // 清除异常 return; } ``` --- ### 示例代码对比(错误 vs 正确) #### ❌ 错误代码 ```c // 假设方法签名错误写成了 (I)Ljava/io/InputStream; jmethodID methodID = env->GetMethodID(cls, "getInputStream", "(I)Ljava/io/InputStream;"); jobject inputStream = env->CallObjectMethod(obj, methodID, 123); // 传入int而非String ``` #### ✅ 正确代码 ```c // 正确签名 (Ljava/lang/String;)Ljava/io/InputStream; jmethodID methodID = env->GetMethodID(cls, "getInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); jstring path = env->NewStringUTF("/data/file.txt"); jobject inputStream = env->CallObjectMethod(obj, methodID, path); ``` --- ### 总结 - **关键点**:方法签名、对象有效性、参数匹配、异常处理。 - **调试建议**:使用 `adb logcat` 查看完整堆栈,定位JNI调用位置。 - **扩展阅读**:参考Oracle官方JNI文档中的 [Type Signatures](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#type_signatures)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值