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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:31:18