永发信息网

如何动态加载android的so文件,如何压缩apk尺寸

答案:1  悬赏:20  手机版
解决时间 2021-03-17 05:58
如何动态加载android的so文件,如何压缩apk尺寸
最佳答案
在Android中调用动态库文件(*.so)都是通过jni的方式,而且往往在apk或jar包中调用so文件时,都要将对应so文件打包进apk或jar包,工程目录下图:

以上方式的存在的问题:
  1、缺少灵活性比较类似静态加载了(不是静态加载),能加载的so文件绑定死了;
  2、但so文件很多或很大时,会导致对应的apk和jar包很大;
  3、不能动态的对so文件更新;

Android中加载so文件的提供的API:
void System.load(String pathName);

说明:
  1、pathName:文件名+文件路劲;
  2、该方法调用成功后so文件中的导出函数都将插入的系统提供的一个映射表(类型Map);

看到以上对System.load(String pathName);的函数说明可定有人会想到将so文件放到一个指定的目录然后再通过参数pathName直接引用该目录的路劲和对应的so文件问题不就解决了吗?
这里有个问题被忽略了,那就是System.load只能加载两个目录路劲下的so文件:
  1、/system/lib ;
  2、安装包的路劲,即:/data/data//…
而且这两个路劲又是有权限保护的不能直接访问;

问题解决方法:
先从网络下载so文件到手机目录(如:/test/device/test.so) –> 将test.so加载到内存(ByteArrayOutputStream) –> 然后保存到对用安装包目录;
具体代码如下:

try {
String localPath = Environment.getExternalStorageDirectory() + path;
Log.v(TAG, "LazyBandingLib localPath:" + localPath);

String[] tokens = mPatterns.split(path);
if (null == tokens tokens.length <= 0
tokens[tokens.length - 1] == "") {
Log.v(TAG, "非法的文件路径!");
return -3;
}
// 开辟一个输入流
File inFile = new File(localPath);
// 判断需加载的文件是否存在
if (!inFile.exists()) {
// 下载远程驱动文件
Log.v(TAG, inFile.getAbsolutePath() + " is not fond!");
return 1;
}
FileInputStream fis = new FileInputStream(inFile);

File dir = context.getDir("libs", Context.MODE_PRIVATE);
// 获取驱动文件输出流
File soFile = new File(dir, tokens[tokens.length - 1]);
if (!soFile.exists()) {
Log.v(TAG, "### " + soFile.getAbsolutePath() + " is not exists");
FileOutputStream fos = new FileOutputStream(soFile);
Log.v(TAG, "FileOutputStream:" + fos.toString() + ",tokens:"
+ tokens[tokens.length - 1]);

// 字节数组输出流,写入到内存中(ram)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
// 从内存到写入到具体文件
fos.write(baos.toByteArray());
// 关闭文件流
baos.close();
fos.close();
}
fis.close();
Log.v(TAG, "### System.load start");
// 加载外设驱动
System.load(soFile.getAbsolutePath());
Log.v(TAG, "### System.load End");

return 0;

} catch (Exception e) {
Log.v(TAG, "Exception " + e.getMessage());
e.printStackTrace();
return -1;

}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
宫廷玉液有女性吃的吗
华帝NO.冀009地址在哪,我要去那里办事
怎样手工制作木船桨
从广西贵港到浙江温州怎么样坐车最快
别克英朗1·6早晨起动发动机抖加不上油门没故
女朋友她妈出轨了,我该怎么安慰她。她妈妈42
江西省电子信息工程学校的出名专业是什么?
2017洪湖市社会保险养老保险基数是多少,比往
“共争青岛归还,同看国贼罢黜;欢呼学生罢课
同济电气工程考研初试考电路分析,复试还是任
杨家湾菜场地址在哪,我要去那里办事
电脑开机5分钟,整栋楼跳闸,怎么回事?把主
太阳能电池计算器晒了太阳还是没用怎么办.可
五芯电缆埋在地下,有一根相线接地了,怎么找到
研究生论文查重什么时候开始实施的
推荐资讯
1983年10日4曰农历是多少
注册中邮件格式如何填写
黑鱼移动充的电源线是不是跟安卓一样
吃夏菇草泡水好或者敖成水喝好
我犯了错误,老婆强烈要求离婚,没给我一小点
月月娃每天睡多长时间为宜
期货公司培训之后要自己出钱开账户实操?
乔富鞋店地址有知道的么?有点事想过去
男友说工作受气就别干了我养你是什么意思
黑莓8100和夏新E70哪种好
(2/2)一个诚实的人,要表里如一 三,要谦虚,
北京奥运会的金牌是用什么做的??
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?