日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/7/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android loadlibrary 更改libPath 路径,指定路径加载.so 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

字數549?閱讀177?評論0?
  • 需求很簡單 ,就是加載指定文件夾下的.so。
  • 原因:android在程序運行的狀態下 ,無法在 data/data/packageName/lib 下寫文件,但可讀。
  • 還有一個引申的問題:data/app-lib/packageName/ 下的.so 和 data/data/packageName/lib 的.so 是什么關系

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 . 獲取當前類的屬性

Object nativeLibraryDirectories=pathList.getClass().getDeclaredField("nativeLibraryDirectories"); ((Field)nativeLibraryDirectories).setAccessible(true);

5 . 設置新的路徑

((Field)nativeLibraryDirectories).set(pathList, file);

6 . 對classloader的操作,對應于BaseDexClassLoader:

public BaseDexClassLoader(String dexPath,File optimizedDirectory,String libraryPath,ClassLoader parent){ super(parent); this.pathList=new DexPathList(this,dexPath,libraryPath,optimizedDirectory); }

7 . dex,library路徑對應于DexPathList, 這部分和熱補丁密切相關,有興趣可以搜下hotfix ,很多開源項目。

privatefinalElement[]dexElements; //這部分就是dex分包的了,熱補丁,熱補丁,熱補丁 privatefinalFile[]nativeLibraryDirectories;//這部分就是 libs 加載路徑了,默認有 /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); //獲取當前類的屬性 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())); //將系統自己的追加上 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); } /** * 僅對4.0以上做支持 * @return */ private static boolean hasDexClassLoader() { try { Class.forName("dalvik.system.BaseDexClassLoader"); return true; } catch (ClassNotFoundException var1) { return false; } }

參考鏈接

  • BaseDexClassLoader 實現

  • DexPathList 實現

  • Java中System.loadLibrary() 的執行過程

總結

以上是生活随笔為你收集整理的android loadlibrary 更改libPath 路径,指定路径加载.so的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。