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的体积就会银差小很多欢迎分享,转载请注明来源:内存溢出
评论列表(0条)