日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

android loadlibrary 更改libPath 路径,指定路径加载.so

發(fā)布時(shí)間:2025/7/14 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android loadlibrary 更改libPath 路径,指定路径加载.so 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.jianshu.com/p/f751be55d1fb

字?jǐn)?shù)549?閱讀177?評(píng)論0?
  • 需求很簡(jiǎn)單 ,就是加載指定文件夾下的.so。
  • 原因:android在程序運(yùn)行的狀態(tài)下 ,無法在 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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。