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命 ...
随机推荐
- Spark生态之SparkR
- ListView inside a ScrollView
ScrollView里面放ListView, ListView无法展开的解决方法 http://stackoverflow.com/questions/18367522/android-list-vi ...
- 74HC595 for STM32 源代码【worldsing笔记】
74HC595是硅结构的CMOS器件, 兼容低电压TTL电路,遵守JEDEC标准. 74HC595是具有8位移位寄存器和一个存储器,三态输出功能. 移位寄存器和存储器是分别的时钟. 数据在SHcp(移 ...
- (莱昂氏unix源代码分析导读-50)LP11行式打印机
by cszhao1980 LP11有两个设备寄存器:状态寄存器(lpsr)和数据缓冲寄存器(lpbuf),可通过以下结构进行访问: 8812: #define LPADDR 0177514 8823 ...
- VirtualBox NAT方式与主机互相通信
之前说过,桥接方式适合在统一的网络环境中使用(一样的网关和许可). 如果网络环境发生改变,那就难堪了 -- 这就是我遇到的问题,公司里每人的IP都是固定的. 解决办法,改为NAT网络地址转换模式. 但 ...
- HDU 2199 Can you solve this equation? (二分 水题)
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- unity3D Socket连接C#server出现unity3D编辑器再次启动连接 unity3D编辑器马上卡死
unity3D Socket与C#server第一次连接时通讯正常.客服端段关闭后.unity3D编辑器再次启动连接 unity3D编辑器马上卡死 原因是Socket处于异步状态,而异步线程是不受Un ...
- java_可变参数构造器 Bulder模式
package com.test1.www; class NutritionFacts { //必须 private int servingSize; private int servings; // ...
- iOS web与js的简单交互
我们在封装网页的时候经常会遇到需要往网页里面的控件添加数据,但是怎么添加又成了难点.本人最近在开发的时候就遇到这样的事,解决之后,来和大家分享一下. //以必应网站为例 [web loadReques ...
- MySQL(16):Select-union(联合查询)
1. Select-union(联合查询) union用于把来自许多SELECT语句的结果组合到一个结果集合中. 用法: SELECT ...UNION [ALL | DISTINCT]SELECT ...