android loadlibrary 更改libPath 路径,指定路径加载.so
生活随笔
收集整理的這篇文章主要介紹了
android loadlibrary 更改libPath 路径,指定路径加载.so
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://www.jianshu.com/p/f751be55d1fb
字?jǐn)?shù)549?閱讀177?評(píng)論0?喜歡0- 需求很簡(jiǎn)單 ,就是加載指定文件夾下的.so。
- 原因:android在程序運(yùn)行的狀態(tài)下 ,無(wú)法在 data/data/packageName/lib 下寫文件,但可讀。
- 還有一個(gè)引申的問題:data/app-lib/packageName/ 下的.so 和 data/data/packageName/lib 的.so 是什么關(guān)系?
1 . 獲取全局的classloader
PathClassLoader pathClassLoader = (PathClassLoader)context.getClassLoader(); DexClassLoader myDexClassLoader = new DexClassLoader(str, context.getDir("dex", 0).getAbsolutePath(), str, context.getClassLoader().getParent());2 . 獲取pathList
Object pathList = getPathList(pathClassLoader);3 . 添加路徑
File[] file = new File[]{ new File("/data/app-lib/pakageName-1"), new File("/data/app-lib/pakageName-2"), new File("/data/data/pakageName/files"), new File("/vendor/lib"), new File("/system/lib") } ;4 . 獲取當(dāng)前類的屬性
Object nativeLibraryDirectories=pathList.getClass().getDeclaredField("nativeLibraryDirectories"); ((Field)nativeLibraryDirectories).setAccessible(true);5 . 設(shè)置新的路徑
((Field)nativeLibraryDirectories).set(pathList, file);6 . 對(duì)classloader的操作,對(duì)應(yīng)于BaseDexClassLoader:
public BaseDexClassLoader(String dexPath,File optimizedDirectory,String libraryPath,ClassLoader parent){ super(parent); this.pathList=new DexPathList(this,dexPath,libraryPath,optimizedDirectory); }7 . dex,library路徑對(duì)應(yīng)于DexPathList, 這部分和熱補(bǔ)丁密切相關(guān),有興趣可以搜下hotfix ,很多開源項(xiàng)目。
privatefinalElement[]dexElements; //這部分就是dex分包的了,熱補(bǔ)丁,熱補(bǔ)丁,熱補(bǔ)丁 privatefinalFile[]nativeLibraryDirectories;//這部分就是 libs 加載路徑了,默認(rèn)有 /vendor/lib system/lib data/app-lib/packageName最后給下代碼:
public static void initNativeDirectory(Application application) { if (hasDexClassLoader()) { try { createNewNativeDir(application); } catch (Exception e) { e.printStackTrace(); } } } private static void createNewNativeDir(Context context) throws Exception{ PathClassLoader pathClassLoader = (PathClassLoader) context.getClassLoader(); Object pathList = getPathList(pathClassLoader); //獲取當(dāng)前類的屬性 Object nativeLibraryDirectories = pathList.getClass().getDeclaredField("nativeLibraryDirectories"); ((Field) nativeLibraryDirectories).setAccessible(true); //獲取 DEXPATHList中的屬性值 File[] files1 = (File[])((Field) nativeLibraryDirectories).get(pathList); Object filesss = Array.newInstance(File.class, files1.length + 1); //添加自定義.so路徑 Array.set(filesss, 0, new File(context.getFilesDir().getAbsolutePath())); //將系統(tǒng)自己的追加上 for(int i = 1;i<files1.length+1;i++){ Array.set(filesss,i,files1[i-1]); } // File[] filesss = new File[file.length+ files1.length]; // filesss[0] = file[0]; // for(int i = 1;i < files1.length+1;i++){ // filesss[i] = files1[i]; // } ((Field) nativeLibraryDirectories).set(pathList, filesss); } private static Object getPathList(Object obj) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { return getField(obj, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList"); } private static Object getField(Object obj, Class cls, String str) throws NoSuchFieldException, IllegalAccessException { Field declaredField = cls.getDeclaredField(str); declaredField.setAccessible(true); return declaredField.get(obj); } /** * 僅對(duì)4.0以上做支持 * @return */ private static boolean hasDexClassLoader() { try { Class.forName("dalvik.system.BaseDexClassLoader"); return true; } catch (ClassNotFoundException var1) { return false; } }參考鏈接
-
BaseDexClassLoader 實(shí)現(xiàn)
-
DexPathList 實(shí)現(xiàn)
- Java中System.loadLibrary() 的執(zhí)行過程
總結(jié)
以上是生活随笔為你收集整理的android loadlibrary 更改libPath 路径,指定路径加载.so的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解DOM节点类型第一篇——12种D
- 下一篇: linux命令s