Closed yanglw closed 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 异常。
mHostContext.getApplicationInfo().nativeLibraryDir
isKnownInstructionSet
例如:系统 App 的 Apk 路径为 /system/app/xxxx.apk ,instructionSet 将会是 xxxx.apk 。
/system/app/xxxx.apk
xxxx.apk
shadow的设计目标不包括支持系统app,所以设计、编码、测试都不会考虑这个场景。
如果你有兼容的方案可以PR。如果你只是想解决自己的问题,我建议这里可以简单的自行针对业务hardcode abi,或者改为针对你的系统的逻辑。
在 Android 5.x 及以上版本中,Shadow 使用下面的方法获取当前的 ABI 类型:
对于 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
。