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命 ...
随机推荐
- Android Studio 模拟器启动问题——黑屏 死机 解决方法
今天用了下Android Studio,出现了一些问题,现在将启动过程中遇到的问题和解决方案列出来,方便大家参考. 安装过程不多说,网上一搜一大把. 那直接说问题吧: 1. 无法启动,报错:Faile ...
- adb pull命令复制android数据库文件.db到电脑
1.win+r cmd进入命令行 2.cd 进入[sdk]/platform-tools目录下 3.执行下面命令行,复制xxx.db到F:/dest adb pull /data/data/[pack ...
- Android问题-selection contains a component,button7,introduced in an ancestor and cannot be deleted.
问题现象: 在开发Android时增加的控件想删除,可是删除时提示“Android问题-selection contains a component,button7,introduced in an ...
- [OC Foundation框架 - 2] NSString 的创建
A. 不可变字符串 void stringCreate() { //Don't need to release memory by this way NSString *str1 = @"S ...
- Oracle-12541:TNS:无监听程序 .
背景:自己机子做oracle服务器,其他机子可以ping得通我的机子,但是jdbc就是连不上,后来用plsql连出现无监听程序.... 我昨天重新安装Oracle后,用PL/SQL Developer ...
- ASP.NET中配置应用程序
1. 配置文件简介 1.1 分类 1.2关系 Machine.Config和Web.Config都是设置应用程序的配置信息,它们按照类似于继承的关系对应用程序起作用. Machine.Config ...
- 提高你的Java代码质量吧:少用静态导入
一.分析 从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...
- 【转载】Android Studio 设置内存大小及原理
http://www.cnblogs.com/justinzhang/p/4274985.html http://tsroad.lofter.com/post/376316_69363ae Andro ...
- Thread学习
1.定义 2.作用 3.和进程的比较 4.多线程(multithreading)的优点和缺陷 5.调度(scheduling) 6.线程相关概念 定义 线程就是最小的可编程指令序列,是进程的子集.一个 ...
- 笔记本禁用自带键盘攻略-------针对shift默认按下的解决方案
长期以来楼主一直被一个问题困扰,就是win8进入界面,输密码时开大写其实是小写,开小写是大写.进入系统以后shift键是默认按下的.一直以为是电脑中毒了.上网查了一些东西,发现可能是因为键盘硬件方面的 ...