Tencent / Shadow

零反射全动态Android插件框架
BSD 3-Clause "New" or "Revised" License
7.46k stars 1.3k forks source link

Android 9.0 系统 App abi 获取错误 #1195

Closed yanglw closed 1 year ago

yanglw commented 1 year ago

在 Android 5.x 及以上版本中,Shadow 使用下面的方法获取当前的 ABI 类型:

private String[] getPluginSupportedAbis() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        String nativeLibraryDir = mHostContext.getApplicationInfo().nativeLibraryDir;
        int nextIndexOfLastSlash = nativeLibraryDir.lastIndexOf('/') + 1;
        String instructionSet = nativeLibraryDir.substring(nextIndexOfLastSlash);
        if (!isKnownInstructionSet(instructionSet)) {
           throw new IllegalStateException("不认识的instructionSet==" + instructionSet);
        }
        boolean is64Bit = is64BitInstructionSet(instructionSet);
        return is64Bit ? Build.SUPPORTED_64_BIT_ABIS : Build.SUPPORTED_32_BIT_ABIS;
    } else {
        String cpuAbi = Build.CPU_ABI;
        String cpuAbi2 = Build.CPU_ABI2;
        ArrayList<String> list = new ArrayList<>(2);
        if (cpuAbi != null && !cpuAbi.isEmpty()) {
            list.add(cpuAbi);
        }
        if (cpuAbi2 != null && !cpuAbi2.isEmpty()) {
            list.add(cpuAbi2);
        }
        return list.toArray(new String[0]);
    }
}

对于 Android 9.0 的系统 App ,内置在 /system/app 或者 /system/priv-app 目录下,系统不会对 so 文件进行解压单独存储。此时通过 mHostContext.getApplicationInfo().nativeLibraryDir 获取到的路径为 Apk 文件的路径,因此 instructionSet 为 Apk 文件的文件名,从而导致 isKnownInstructionSet 方法返回 false ,进而抛出 “不认识的instructionSet” 的 IllegalStateException 异常。

例如:系统 App 的 Apk 路径为 /system/app/xxxx.apk ,instructionSet 将会是 xxxx.apk

shifujun commented 1 year ago

shadow的设计目标不包括支持系统app,所以设计、编码、测试都不会考虑这个场景。

如果你有兼容的方案可以PR。如果你只是想解决自己的问题,我建议这里可以简单的自行针对业务hardcode abi,或者改为针对你的系统的逻辑。