JNI检测到无效Modified UTF-8错误,依赖库字符串致应用崩溃求助
JNI非法UTF-8字节崩溃修复(依赖库引发,仅部分设备出现)
错误日志
java_vm_ext.cc:594] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0xa java_vm_ext.cc:594] string: 'arch_disk_io_� java_vm_ext.cc:594] ' java_vm_ext.cc:594] input: '0x61 0x72 0x63 0x68 0x5f 0x64 0x69 0x73 0x6b 0x5f 0x69 0x6f 0x5f 0xe0 0xa7 <0x0a>' java_vm_ext.cc:594] in call to NewStringUTF java_vm_ext.cc:594] from boolean android.os.Process.readProcFile(java.lang.String, int[], java.lang.String[], long[], float[]) 2023-02-07 18:26:40.796 13309-13331/om.friendimobile.vm D/VRI[SplashActivity]: dispatchAppVisibility visible:false
问题分析
崩溃根源是JNI层检测到非法的Modified UTF-8字节(0xa),触发点是android.os.Process.readProcFile调用NewStringUTF时,传入了包含无效字符的字符串arch_disk_io_�。这个字符串来自AndroidX的DefaultTaskExecutor类,仅在部分设备出现,原因是这些设备的系统proc文件输出包含非标准UTF-8字符,而依赖库未做兼容处理。
修复方案
拦截清理非法字符
编写工具类过滤字符串中的非法UTF-8字节,比如:import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.StandardCharsets; public class StringUtils { public static String cleanInvalidUtf8(String input) { if (input == null) return null; // 用ISO-8859-1读取字节再转UTF-8,自动替换非法字符 ByteBuffer buffer = ByteBuffer.wrap(input.getBytes(StandardCharsets.ISO_8859_1)); CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer); // 额外过滤不可见控制字符 return charBuffer.toString().replaceAll("[\\x00-\\x1F\\x7F-\\x9F]", ""); } }再通过反射或包装
readProcFile方法,对返回结果调用这个工具方法后再使用。升级AndroidX依赖
检查当前androidx.core版本,旧版本可能存在兼容性漏洞,直接升级到最新稳定版(比如androidx.core:core-ktx:1.12.0及以上),官方可能已修复该问题。替换默认TaskExecutor
实现自定义TaskExecutor,复制DefaultTaskExecutor的逻辑,在涉及读取proc文件的环节加入字符清理,然后在Application初始化时替换:import android.app.Application; import androidx.arch.core.executor.ArchTaskExecutor; import androidx.arch.core.executor.TaskExecutor; public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); ArchTaskExecutor.getInstance().setDelegate(new CustomTaskExecutor()); } private static class CustomTaskExecutor extends TaskExecutor { // 复制DefaultTaskExecutor的实现,在读取proc相关内容时调用StringUtils.cleanInvalidUtf8处理 } }规避触发场景
排查DefaultTaskExecutor读取该proc文件的触发时机(比如后台任务调度),调整任务执行时机(比如延后到首页加载完成后),减少该代码路径的执行概率。
内容的提问来源于stack exchange,提问作者Shaifali Rajput
相关产品推荐
相关产品推荐

