Android升级64是今年Google强制执行的一项规定,国内应用市场也应该快实施了,所以升级64位是必须执行的。其实Android中升级64位主要是SO升级。
1.动态加载so
Android其实从5.0以后就支持64位,但是现在市场上的app大多不支持64,只放入32位的so,主要支持多个cpu架构so的体积过大。当app只有32位so,app就会以32模式运行,当app有64位so,app就会以64位运行,所以动态加载so的时候需要加载对应cpu架构的so。Android中动态加载so的方法是System.load
, 此方法在加载32位so的时候没有问题,但是在加载64位so的时候,部分低版本手机机型出现UnsatisfiedLinkError
错误。其实查阅了很多资料也没有找到根本的问题,只能想其他方案实现,过程中也一直没有找到新的方法,后来灵光一闪,可以参考插件化加载方案,加载so流程。直接将so路径放置到系统路径里面,通过System.loadLibrary(fileName)
加载so。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| private static void install(ClassLoader classLoader, File folder) throws Throwable { Field pathListField = ReflectUtil.findField(classLoader, "pathList"); Object dexPathList = pathListField.get(classLoader); Field nativeLibraryDirectories = ReflectUtil.findField(dexPathList, "nativeLibraryDirectories");
List<File> libDirs = (List<File>) nativeLibraryDirectories.get(dexPathList); //去重 if (libDirs == null) { libDirs = new ArrayList<>(2); } final Iterator<File> libDirIt = libDirs.iterator(); while (libDirIt.hasNext()) { final File libDir = libDirIt.next(); if (folder.equals(libDir) || folder.equals(lastSoDir)) { libDirIt.remove(); Log.d(TAG, "dq libDirIt.remove()" + folder.getAbsolutePath()); break; } }
libDirs.add(0, folder); //system/lib Field systemNativeLibraryDirectories = ReflectUtil.findField(dexPathList, "systemNativeLibraryDirectories"); List<File> systemLibDirs = (List<File>) systemNativeLibraryDirectories.get(dexPathList);
//判空 if (systemLibDirs == null) { systemLibDirs = new ArrayList<>(2); } Log.d(TAG, "dq systemLibDirs,size=" + systemLibDirs.size());
Method makePathElements = ReflectUtil.findMethod(dexPathList, "makePathElements", List.class); libDirs.addAll(systemLibDirs);
Object[] elements = (Object[]) makePathElements.invoke(dexPathList, libDirs); Field nativeLibraryPathElements = ReflectUtil.findField(dexPathList, "nativeLibraryPathElements"); nativeLibraryPathElements.setAccessible(true); nativeLibraryPathElements.set(dexPathList, elements); }
|
2.Webview闪退问题
我们app升级64位上线后,莫名其妙出现了很多webview navtive的一些闪退,猜测大概率是升级64位导致的。查阅资料说是webview缓存导致,清除webview cpu缓存可以解决
data/data/com.sammekl.myapp/app_webview/GPUCache
删除路径文件,但是删除完成后发现无效,需要删除app_webview整个目录。
1 2 3 4 5 6 7 8
| backtrace: #00 pc 000000000076eb50 /vendor/lib/libllvm-glnext.so (ShaderObjects::loadProgramBinary(CompilerContext*, void*, unsigned int, QGLC_LINKPROGRAM_RESULT*)+855) #01 pc 00000000006ddba5 /vendor/lib/libllvm-glnext.so (CompilerContext::loadProgramBinary(void*, unsigned int, QGLC_LINKPROGRAM_RESULT*)+108) #02 pc 000000000077fb73 /vendor/lib/libllvm-glnext.so (QGLCLoadProgramBinary(void*, void*, unsigned int, QGLC_LINKPROGRAM_RESULT*)+54) #03 pc 00000000001612b1 /vendor/lib/egl/libGLESv2_adreno.so (EsxShaderCompiler::LoadProgramBinaryBlob(EsxContext*, EsxProgram*, void const*, unsigned int, EsxInfoLog*)+164) #04 pc 0000000000140191 /vendor/lib/egl/libGLESv2_adreno.so (EsxProgram::LoadProgramBinary(EsxContext*, unsigned int, void const*, int)+186) #05 pc 00000000000aff67 /vendor/lib/egl/libGLESv2_adreno.so (EsxContext::GlProgramBinary(unsigned int, unsigned int, void const*, int)+230) #06 pc 00000000000991d9 /vendor/lib/egl/libGLESv2_adreno.so (glProgramBinary+40)
|
参考资料