热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android中将独立SO库封装进JAR包并实现SO库的加载与调用

在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。

Android将so库封装到jar包中并加载其中的so库

之前写过将jar包和so库封装到jar包中的文章,但是没有考虑别人调用时需要加载so库的问题。因为so库放入jar之后,so就不是一个独立的.so文件了,用System.load()加载就会提示找不到这个库,所以要想加载这个so 就需要把so 从jar 中提取出来,保存为临时文件,然后再加载。但是不能直接提取.so文件,需要把.so文件改成.jet文件封装到jar中,再进行提取拷贝。

如何建立一个项目以及项目的结构还有模块我就不说,可以看我之前的文章:

1.将so后缀改成.jet,然后放到下图目录中,如果有多个cpu架构可以放多个。

092596426bd8e03343f0dbe24a75b415.png

2.修改build.gradle文件task makeJar(type: Jar)方法

apply plugin: 'com.android.library'

android {

compileSdkVersion 29

defaultConfig {

minSdkVersion 22

targetSdkVersion 29

versionCode 1

versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

sourceSets {

main {

// jni.srcDirs = []

// jniLibs.srcDirs = ['src/main/jniLibs']//设置目标的so存放路径

}

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'

}

lintOptions {

abortOnError false

}

}

task makeJar(type: Jar){

//删除存在的

delete 'build/libs/newsdk.jar' //删除存在的

archivesBaseName = 'newsdk' //输出的jar包名称

from(project.zipTree('build/intermediates/packaged-classes/release/classes.jar'))

from(project.zipTree('build/intermediates/packaged-classes/release/libs/AMap_Search_V7.1.0_20191030.jar')) //需要打包的第三方jar包

// from fileTree(dir: "src/main/java", include: "**/*.so") //把src/main/java目录下包含的所有.so文件封装到jar包

from fileTree(dir: "src/main/java", include: "**/*.jet") //把src/main/java目录下包含的所有.jet文件封装到jar包

destinatiOnDir= file('build/libs') //打成jar包后存放的文件目录

}

makeJar.dependsOn(build)

}

dependencies {

testImplementation 'junit:junit:4.12'

implementation files('libs/AMap_Search_V7.1.0_20191030.jar')

}

3.点击makejar编译出jar包,将其引入到项目中,打开可以看到里面包含了a.jet和b.jet文件,如下图。

b3fb1fdd2e04c14c07e2e513dbe8d2a2.png

4.在项目中通过Java代码加载jar中的so库,这里只展示加载a.so库。原理:获取a.jet的文件流,再把文件流输入到临时文件a.so中, System.load()方法加载a.so文件(简单点说,就是把a.jet文件拷贝出来),这样就可以了。

static {

try {

InputStream is = null;

is = SysLoad.class.getResourceAsStream("/com/example/libraryb/arm64-v8a/a.jet");

File tempFile = File.createTempFile("a", ".so");

FileOutputStream fos = new FileOutputStream(tempFile);

int i;

byte[] buf = new byte[1024];

while ((i = is.read(buf)) != -1) {

fos.write(buf, 0, i);

}

is.close();

fos.close();

System.load(tempFile.getAbsolutePath());

} catch (IOException e) {

e.printStackTrace();

}

}

注意:提取a.jet文件时,要注意改一下路径,改成你自己的。

来源: https://blog.csdn.net/weixin_42574892/article/details/105707035



推荐阅读
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 基于机器学习的人脸识别系统实现
    本文介绍了一种使用机器学习技术构建人脸识别系统的实践案例。通过结合Python编程语言和深度学习框架,详细展示了从数据预处理到模型训练的完整流程,并提供了代码示例。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 简化报表生成:EasyReport工具的全面解析
    本文详细介绍了EasyReport,一个易于使用的开源Web报表工具。该工具支持Hadoop、HBase及多种关系型数据库,能够将SQL查询结果转换为HTML表格,并提供Excel导出、图表显示和表头冻结等功能。 ... [详细]
  • 使用Nginx反向代理实现多域名端口映射
    本文介绍如何通过配置本地hosts文件和Nginx反向代理,实现多个虚拟域名的端口映射,使用户可以通过标准HTTP端口80访问不同后端服务。 ... [详细]
  • 历经三十年的开发,Mathematica 已成为技术计算领域的标杆,为全球的技术创新者、教育工作者、学生及其他用户提供了一个领先的计算平台。最新版本 Mathematica 12.3.1 增加了多项核心语言、数学计算、可视化和图形处理的新功能。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • This post discusses an issue encountered while using the @name annotation in documentation generation, specifically regarding nested class processing and unexpected output. ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 本文详细介绍了如何解压并安装MySQL集群压缩包,创建用户和组,初始化数据库,配置环境变量,并启动相关服务。此外,还提供了详细的命令行操作步骤和常见问题的解决方案。 ... [详细]
  • 本文详细介绍了Linux系统中的进程管理函数,涵盖了获取进程ID、用户ID、创建子进程、信号处理等关键操作。通过这些函数,开发者可以更好地控制和管理进程行为。 ... [详细]
  • 本文详细介绍了如何在云服务器上配置Nginx、Tomcat、JDK和MySQL。涵盖从下载、安装到配置的完整步骤,帮助读者快速搭建Java Web开发环境。 ... [详细]
  • 本文将详细介绍如何在没有显示器的情况下,使用Raspberry Pi Imager为树莓派4B安装操作系统,并进行基本配置,包括设置SSH、WiFi连接以及更新软件源。 ... [详细]
author-avatar
小天
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有