android loadlibrary 更改libPath 路径,指定路径加载.so
http://www.jianshu.com/p/f751be55d1fb
- 需求很简单 ,就是加载指定文件夹下的.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的更多相关文章
- android -------- 打开本地浏览器或指定浏览器加载,打电话,打开第三方app
开发中常常有打开本地浏览器加载url或者指定浏览器加载, 还有打开第三方app, 如 打开高德地图 百度地图等 在Android程序中我们可以通过发送隐式Intent来启动系统默认的浏览器. 如果手机 ...
- [Android] 输入系统(三):加载按键映射
映射表基本概念 由于Android调用getEvents得到的key是linux发送过来的scan code,而Android处理的是类似于KEY_UP这种统一类型的key code,因此需要有映射表 ...
- 携程Android App的插件化和动态加载框架
携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...
- Android基于JsBridge封装的高效带加载进度的WebView
Tamic http://blog.csdn.net/sk719887916/article/details/52402470 概述 从去年4月项目就一直用起了JsBridge,前面也针对jsBrid ...
- Android Volley和Gson实现网络数据加载
Android Volley和Gson实现网络数据加载 先看接口 1 升级接口 http://s.meibeike.com/mcloud/ota/cloudService POST请求 参数列表如下 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)
正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...
- Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案
转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...
- Android中使用WebView, WebChromeClient和WebViewClient加载网页 (能够执行js)
Android中使用WebView, WebChromeClient和WebViewClient加载网页 在android应用中,有时要加载一个网页,如果能配上一个进度条就更好了,而android ...
- Linux命令备忘录:mount用于加载文件系统到指定的加载点
mount命令用于加载文件系统到指定的加载点.此命令的最常用于挂载cdrom,使我们可以访问cdrom中的数据,因为你将光盘插入cdrom中,Linux并不会自动挂载,必须使用Linux mount命 ...
随机推荐
- C#实现异步编程的两个简单机制(异步委托&定时器)及Thread实现多线程
创建线程的常用方法:异步委托.定时器.Thread类 理解程序.进程.线程三者之间的区别:简而言之,一个程序至少有一个进程,一个进程至少有一个线程进程就是在内存中运行的程序(即运行着的程序):一个进程 ...
- MVC产生验证码
来源地址: http://www.cnblogs.com/insus/p/3629269.html
- Web- 一些标签样式
网上找来的.有点用 1.只有下划线的文本框:<input style="border:0;border-bottom:1 solid black;background:;"& ...
- Java Web连接各种数据库方式汇总
1.Oracle数据库(thin模式) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String ...
- Android多媒体-人脸识别
1. 相关背景 Google 于2006年8月收购Neven Vision 公司 (该公司拥有 10 多项应用于移动设备领域的图像识别的专利),以此获得了图像识别的技术,并不是常快应用到免费的 Pic ...
- Android提高21篇之二:SurfaceView的基本使用方法
上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍Su ...
- Nginx加多个tomcat实现负载均衡,动静分离
一:Nginx+Tomcat的动静分离 所谓动静分离就是通过nginx(或apache等)来处理用户端请求的图片.html等静态的文件,tomcat(或weblogic)处理jsp.do等动态文件,从 ...
- [转]Log4Net中配置文件的解释
FROM:http://www.cnblogs.com/kissazi2/p/3392605.html 一个完整的配置文件的例子如下所示 <log4net> <!-- 错误日志类-- ...
- 详解C中volatile关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...
- 多系统通讯-DotNetMQ
很久都没有写博客了,从15年4月份一直忙到现在,我才有时间去做梳理和总结,因为我提离职了,感觉整个世界突然变得不一样,随着而来的就是心情的放松,写一篇文章也是对过去一年多工作的梳理,加深印象 积累和沉 ...