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

字数549 阅读177 评论0 喜欢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;
}
}

参考链接

android loadlibrary 更改libPath 路径,指定路径加载.so的更多相关文章

  1. android -------- 打开本地浏览器或指定浏览器加载,打电话,打开第三方app

    开发中常常有打开本地浏览器加载url或者指定浏览器加载, 还有打开第三方app, 如 打开高德地图 百度地图等 在Android程序中我们可以通过发送隐式Intent来启动系统默认的浏览器. 如果手机 ...

  2. [Android] 输入系统(三):加载按键映射

    映射表基本概念 由于Android调用getEvents得到的key是linux发送过来的scan code,而Android处理的是类似于KEY_UP这种统一类型的key code,因此需要有映射表 ...

  3. 携程Android App的插件化和动态加载框架

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

  4. Android基于JsBridge封装的高效带加载进度的WebView

    Tamic http://blog.csdn.net/sk719887916/article/details/52402470 概述 从去年4月项目就一直用起了JsBridge,前面也针对jsBrid ...

  5. Android Volley和Gson实现网络数据加载

    Android Volley和Gson实现网络数据加载 先看接口 1 升级接口 http://s.meibeike.com/mcloud/ota/cloudService POST请求 参数列表如下 ...

  6. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

    正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...

  7. Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...

  8. Android中使用WebView, WebChromeClient和WebViewClient加载网页 (能够执行js)

    Android中使用WebView, WebChromeClient和WebViewClient加载网页   在android应用中,有时要加载一个网页,如果能配上一个进度条就更好了,而android ...

  9. Linux命令备忘录:mount用于加载文件系统到指定的加载点

    mount命令用于加载文件系统到指定的加载点.此命令的最常用于挂载cdrom,使我们可以访问cdrom中的数据,因为你将光盘插入cdrom中,Linux并不会自动挂载,必须使用Linux mount命 ...

随机推荐

  1. C#实现异步编程的两个简单机制(异步委托&定时器)及Thread实现多线程

    创建线程的常用方法:异步委托.定时器.Thread类 理解程序.进程.线程三者之间的区别:简而言之,一个程序至少有一个进程,一个进程至少有一个线程进程就是在内存中运行的程序(即运行着的程序):一个进程 ...

  2. MVC产生验证码

    来源地址: http://www.cnblogs.com/insus/p/3629269.html

  3. Web- 一些标签样式

    网上找来的.有点用 1.只有下划线的文本框:<input style="border:0;border-bottom:1 solid black;background:;"& ...

  4. Java Web连接各种数据库方式汇总

    1.Oracle数据库(thin模式) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String ...

  5. Android多媒体-人脸识别

    1. 相关背景 Google 于2006年8月收购Neven Vision 公司 (该公司拥有 10 多项应用于移动设备领域的图像识别的专利),以此获得了图像识别的技术,并不是常快应用到免费的 Pic ...

  6. Android提高21篇之二:SurfaceView的基本使用方法

    上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍Su ...

  7. Nginx加多个tomcat实现负载均衡,动静分离

    一:Nginx+Tomcat的动静分离 所谓动静分离就是通过nginx(或apache等)来处理用户端请求的图片.html等静态的文件,tomcat(或weblogic)处理jsp.do等动态文件,从 ...

  8. [转]Log4Net中配置文件的解释

    FROM:http://www.cnblogs.com/kissazi2/p/3392605.html 一个完整的配置文件的例子如下所示 <log4net> <!-- 错误日志类-- ...

  9. 详解C中volatile关键字

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

  10. 多系统通讯-DotNetMQ

    很久都没有写博客了,从15年4月份一直忙到现在,我才有时间去做梳理和总结,因为我提离职了,感觉整个世界突然变得不一样,随着而来的就是心情的放松,写一篇文章也是对过去一年多工作的梳理,加深印象 积累和沉 ...