zoukankan      html  css  js  c++  java
  • 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;
            }
        }

    参考链接

  • 相关阅读:
    JavaPersistenceWithMyBatis3笔记-第2章Bootstrapping MyBatis-001XMl形式和Java形式
    JavaPersistenceWithMyBatis3笔记-第1章-001
    算法Sedgewick第四版-第1章基础-2.3 Quicksort-001快速排序
    算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-008排序算法的复杂度(比较次数的上下限)
    算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-007归并排序(自下而上)
    算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)
    算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-005插入排序的改进版
    算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-004希尔排序法(Shell Sort)
    常用的Expression调用形式
    C#调用JAVA接口WSSE方式用WebClient方式
  • 原文地址:https://www.cnblogs.com/jukan/p/5786765.html
Copyright © 2011-2022 走看看