如何动态加载定位的 SO 文件

如何动态加载定位的 SO 文件,第1张

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/<packagename>/…

而且这两个路劲又是有权限保护的不能直接访问

问题解决方法:

先从网络下载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

}

加载so分为动态加载和静态加载。

静态加载:System.loadLibrary(String libname),来直接加载,对于一个app它只能加载system的和我们自己添加到jniLibs下的so文案。静态加载会去这些路径找到渣坦羡对应的库否则会抛出异常。packagename/system/lib

动态加载:System.load(String filePath)来加载filePath对应路径下的so文件,这个路径不可以是外置SDcard等拓展路径,必须是/data/**{package}下

最理想的方案就是直接指定packagename/system/lib,

既然是最理想的,那么这方案肯定是不行的,因为这个目录,只有读的如拍权限,没有写的权限.

拿root的 手机可以测试,我们手动把so.拷贝到这个目录是可以信帆的.

so文件是用c语言编写编译在安卓平台的动态链接库…但是加载是根据你的java代码决定的…JNI编程中,何时调用C文件森搏型,也是你代码指定调用的,不调用时不加载,把应用的核心逻辑算法都写成库文件,这此猜样apk的体积就会银差小很多


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12222282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存