当前位置: 首页 > news >正文

Android 源码中jni项目 加载so目录小结

Android 源码中jni项目 加载so目录小结

文章目录

  • Android 源码中jni项目 加载so目录小结
    • 一、前言
    • 二、so目录验证测试
      • 1、jni so文件错误报错
        • (1)报错1 - 未找到so文件:
        • (2)报错2 - so文件中未找到native方法:
      • 2、验证的几种情况
        • (1)apk下面的 lib/arm64/ 放置正确的so文件
        • (2)apk下面的 lib/arm64/ 放置错误的so文件
        • 所以上面两个测试,验证了 lib/arm64/ 目录才是首先选择的目录。
        • (3)apk下面的 lib/arm64/ 不放置so文件
          • ① system/lib 、vendor/lib64 、vendor/lib放置正确的so文件
        • 测试验证了,system/lib 、vendor/lib64 、vendor/lib 系统不会读取里面的so。
          • ② system/lib64 放置正确的so文件
          • ③system/lib64 放置错误的so文件
        • 测试验证了,系统应用会读取 system/lib64/ 下面的so。
    • 三、其他
      • 1、系统源码中加载so的具体实现
      • 2、Android JNI SO库和对应的CPU架构详解
      • 3、Android 系统源码项目加载预编好的so库

一、前言

如何实现把so放到Android设备目录system/lib64下面,系统应用apk就能自动获取里面的so?

如果实现了这个功能,后续修改了jni具体功能实现,

就不用修改这个apk的代码,只要替换这个so就可以完成不同的实现了。

其实这个功能不难,只要是系统源码编译的应用就可以;

具体如何编译可以看本文最后的介绍。

本文主要介绍一下,系统源码应用编译后,load so的顺序:

顺序就是优先apk目录下的 lib/arm64/,然后 system/lib64/,有的还会加载 vendor/lib64/

具体实现是cpp底层的,这里不做具体分析。

二、so目录验证测试

jni加载so代码:

static {System.loadLibrary("native-lib");
}

这里是没有写so路径的,so的固定命名规则是前面加 lib 后面加.so,所以正确的搜命名是:libnative-lib.so

这里拿一个其他错误的libnative-lib.so和一个正确的libnative-lib.so验证测试。

目录分别测试:apk下面的lib/arm64/,system/lib, system/lib64, vendor/lib64,vendor/lib

应用运行后保存主要有两种,一个是找不到so,一个是so找不到jni的方法。

1、jni so文件错误报错

(1)报错1 - 未找到so文件:
2024-09-04 16:10:42.987 1593-1593/? E/AndroidRuntime: FATAL EXCEPTION: mainProcess: com.demo.jnicallback, PID: 1593java.lang.UnsatisfiedLinkError: dlopen failed: library "libnative-lib.so" not foundat java.lang.Runtime.loadLibrary0(Runtime.java:1077)at java.lang.Runtime.loadLibrary0(Runtime.java:998)at java.lang.System.loadLibrary(System.java:1661)at com.liwenzhi.jnidemo.JniClass.<clinit>(JniClass.java:16)at com.demo.jnicallback.MainActivity.onCreate(MainActivity.java:27)

上面那几个目录下都没有so文件就会报这个错误。

(2)报错2 - so文件中未找到native方法:
    --------- beginning of crash
2024-09-04 15:32:04.294 1600-1600/? E/AndroidRuntime: FATAL EXCEPTION: mainProcess: com.demo.jnicallback, PID: 1600java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.liwenzhi.jnidemo.JniClass.stringFromJNI() (tried Java_com_liwenzhi_jnidemo_JniClass_stringFromJNI and Java_com_liwenzhi_jnidemo_JniClass_stringFromJNI__)at com.liwenzhi.jnidemo.JniClass.stringFromJNI(Native Method)at com.demo.jnicallback.MainActivity.onCreate(MainActivity.java:28)

有so但是so里面的实现方法,包名不正常或者不存在这个 native方法就会报上面这个错误。

2、验证的几种情况

(1)apk下面的 lib/arm64/ 放置正确的so文件

其他目录不管放置错误的so文件还是不放置so文件都是不会报错的;

(2)apk下面的 lib/arm64/ 放置错误的so文件

其他目录不管放置正确的so文件还是不放置so文件都是会报错native方法不一致;

所以上面两个测试,验证了 lib/arm64/ 目录才是首先选择的目录。
(3)apk下面的 lib/arm64/ 不放置so文件
① system/lib 、vendor/lib64 、vendor/lib放置正确的so文件

运行后都是报错未找到so文件错误

测试验证了,system/lib 、vendor/lib64 、vendor/lib 系统不会读取里面的so。

其实这个情况不是绝对的,后面简单说一下,这个和应用的32位、64位有关,但是现在应用基本都是64位的了。

② system/lib64 放置正确的so文件

应用不会报错;

③system/lib64 放置错误的so文件

应用会报错native方法不一致;

测试验证了,系统应用会读取 system/lib64/ 下面的so。

上面几个测试,就验证了 so加载的顺序优先apk目录下的 lib/arm64/,然后 system/lib64/。

其实知道就行了,没啥太大必要进行验证测试。

三、其他

1、系统源码中加载so的具体实现

安卓so加载流程源码分析

https://oacia.dev/android-load-so/

android so的加载流程(Android 13~14)

https://blog.csdn.net/qq_61253776/article/details/141675312

在系统中确实看到有应用是加载到了 vendor/lib64 下面的so,

但是不知道为啥我编的系统应用无法加载到这个目录下面的so,这个有待研究!

2、Android JNI SO库和对应的CPU架构详解

armeabi:第五代、第六代ARM处理器,使用软件浮点运算,很古老的手机是这架构, 出现在2000年左右 。(32位)armeabi-v7a:第七代ARM处理器,使用硬件浮点运算,2018年以前手机主流架构, 2007年开始出现 。(32位)arm64-v8a:第八代64位处理器,当前主流架构, 2014年左右出现。(64位)x86/x86-64:Intel处理器,Android模拟器用得比较多。 
X86_64与X64都是讲的同一个东西(64位) 。x86(32位)每一种CPU架构对应一个ABI,ABI定义了二进制文件(比如SO)如何运行在相应的系统平台。

详细介绍:

https://blog.csdn.net/wenzhi20102321/article/details/137064391

看看so和cpu框架,看看时间,大概就知道为啥现在应用都是64位框架的了,不可能再用十几年前的应用了吧。

如果真的使用32位的cpu框架,

apk下面的so目录是: lib/armeabi-v7a

system下面的so目录是 :system/lib

有的系统会在system/lib 和 system/lib64 都放so,防止运行的是32位的cpu框架的应用报错。

3、Android 系统源码项目加载预编好的so库

本来以为只是介绍一下编译使用的Android.mk或者Android.bp就可以了,

但是事实有点出乎意料,总结下来发现收获了一些知识点;

普通应用开发不一定用到这个知识,但是系统编译开发会用到这个知识,并且有的相关文件还不好解决。

https://blog.csdn.net/wenzhi20102321/article/details/141968262

相关文章:

Android 源码中jni项目 加载so目录小结

Android 源码中jni项目 加载so目录小结 文章目录 Android 源码中jni项目 加载so目录小结一、前言二、so目录验证测试1、jni so文件错误报错&#xff08;1&#xff09;报错1 - 未找到so文件&#xff1a;&#xff08;2&#xff09;报错2 - so文件中未找到native方法&#xff1a; …...

24/9/6算法笔记 kaggle 房屋价格

预测模型主要分为两大类&#xff1a; 回归模型&#xff1a;当你的目标变量是连续的数值时&#xff0c;你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;岭回归…...

【MA35D1】buildroot 编译使用经验

文章目录 芯片介绍Buildroot开发Linux实践环境搭建代码获取编译执行步骤&#xff08;仅适用于我公司产品&#xff09; 后续有需要更改的输出文件目录 芯片介绍 NuMicro MA35D1系列为一颗异核同构的多核心微处理器&#xff0c;适用于高端 Edge IIoT Gateway。它是基于双核 64 位…...

排查 MyBatis XML 配置中的 IF 语句与传值名称不匹配的 Bug

文章目录 本文档只是为了留档方便以后工作运维&#xff0c;或者给同事分享文档内容比较简陋命令也不是特别全&#xff0c;不适合小白观看&#xff0c;如有不懂可以私信&#xff0c;上班期间都是在得 前言&#xff0c;在改一个bug得时候发现一个有意思得问题&#xff0c;就是myb…...

数字证书与公钥基础设施

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;数字证书 数字证书是由第三方可信机构&#xff08;一般是证书服务器&#xff09;颁发的数字证书&#xff0c;可以证明身份的可信度。 数字证书具有以下特点以及性质&#xff1a…...

拥抱数智化,JNPF低代码平台如何推动企业转型升级

随着信息技术的飞速发展&#xff0c;企业面临的市场竞争日益激烈&#xff0c;传统的业务流程和管理模式已经难以满足快速变化的市场需求。数智化转型成为企业持续发展的必由之路。在这一过程中&#xff0c;低代码开发平台扮演了至关重要的角色。本文将探讨JNPF低代码平台如何助…...

Linux shell脚本 (十二)case语句_linux awk case语句

​ case工作方式如上所示。取值后面必须为关键字 in&#xff0c;每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后&#xff0c;其间所有命令开始执行直至 ;;。;; 与其他语言中的 break 类似&#xff0c;意思是跳到整个 case 语句的最后。​ 取值将…...

【二等奖成品论文】2024年数学建模国赛B题25页成品论文+完整matlab代码、python代码等(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024年数学建模国赛B题31页完整建模过程25页成品论文matlab/python代码等&#xff08;后续会更新「首先来看看目前已有的资料&#xff0c;还会…...

国内快速高效下载 HuggingFace上的各种大语言模型

预先安装&#xff1a; apt install aria2 # sudo apt install aria2apt install git-lfs # sudo apt install git-lfs下载hfd wget https://hf-mirror.com/hfd/hfd.shchmod ax hfd.sh设置环境变量 Linux export HF_ENDPOINThttps://hf-mirror.comWindows $env:HF_ENDPOINT…...

linux proxy 【linux 代理】

服务端 略 客户端 proxy_url"http://192.168.21.101:7890" export no_proxy"192.168.21.2,10.0.0.0/8,192.168.0.0/16,localhost,127.0.0.0/8,.coding.net,.tencentyun.com,.myqcloud.com" # proxy settings enable_proxy() {export http_proxy"${…...

AcWing907. 区间覆盖

参考的视频讲解&#xff1a;↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【贪心算法08-区间问题03-区间覆盖】 每次贪心就是选择左端点里面&#xff1c;起始端点里面右边界最大的&#xff0c;这样就是保证了最少区间个数! 然后每次迭代都会更新一次起始端点st&#xff0c;反复运用本算法…...

Unity TMP (TextMeshPro) 更新中文字符集

TMP更新中文字符集 1 字符集缺失说明2 字体的字符表2.1 字符表更新模式&#xff1a;动态2.2 字符表更新模式&#xff1a;静态 3 更新字符集步骤3.1 打开纹理更新面板3.1 导入文本文件3.3 关于警告处理 4 修改TMP默认字体设置 1 字符集缺失说明 使用TMP显示中文需要用到中文字体…...

Leetcode3259. 超级饮料的最大强化能量

Every day a Leetcode 题目来源&#xff1a;3259. 超级饮料的最大强化能量 解法1&#xff1a;记忆化搜索 本题的状态定义 dfs(i,j)。其中 j0,1&#xff0c;分别表示最后选的是 energyDrinkA[i] 还是 energyDrinkB[i]。 为方便实现&#xff0c;把 energyDrinkA 和 energyDri…...

Java题集(由入门到精通)03

此系列文章收录大量Java经典代码题&#xff08;也可以算是leetcode刷题指南&#xff09;&#xff0c;希望可以与大家一起努力学好Java。3、2、1&#xff0c;请看&#xff01; 目录 1.创建学生成绩表 2.冒泡排序 3.模拟彩票中奖 4.杨辉三角 1.创建学生成绩表 输入n个学生的…...

zblog自动生成文章插件(百度AI写作配图,图文并茂)

最近工作比较忙&#xff0c;导致自己的几个网站都无法手动更新&#xff0c;于是乎也想偷个懒把&#xff0c;让AI帮忙打理下自己的网站。我接触chatgpt等AI工具还是比较早了&#xff0c;从openai推出gpt3.5就一直在用&#xff0c;说实话&#xff0c;开始的时候用AI自动更新网站还…...

华为 HCIP-Datacom H12-821 题库 (4)

有需要题库的可以看主页置顶 V群仅进行学习交流 1.缺省情况下&#xff0c;广播型网络中运行 IS-IS 的路由器&#xff0c;DIS 发送 CSNP报文的周期为多少秒&#xff1f; A、10 B、3.3 C、30 D、40 答案&#xff1a;A 解析&#xff1a; 广播型网络中运行 IS-IS 的路由器&am…...

使用seq_file

在《使用procfs》一文的源码示例中有说到proc文件系统每次读取的数据只能是1个页,如果超过则需多次读取,这样的话会增加读取次数,增多系统调用次数,影响了整体的效率,故而才有seq file序列文件的出现,该项功能使得内核对于大文件的读取更加容易。 对于seq file,其结构…...

期货赫兹量化-种群优化算法:进化策略,(μ,λ)-ES 和 (μ+λ)-ES

进化策略&#xff08;Evolution Strategies, ES&#xff09;是一种启发式算法&#xff0c;旨在模仿自然选择的过程来解决复杂的优化问题&#xff0c;尤其在没有显式解、或搜索空间巨大的情况下表现良好。基于自然界的进化原理&#xff0c;进化策略通过突变、选择等遗传算子迭代…...

pytest实战演练

pytest实战演练 pycharm常见操作 创建项目使用虚拟环境 创建文件夹的时候建议使用的创建方式 这样创建是因为python3.0版本之后导包无区别&#xff0c;之前版本导包会报错的 _init_.py文件中建议为空不写内容 _all_[]的含义 是将列表中的方法或变量或类暴漏出去便于使用的生效…...

7、关于LoFTR

7、关于LoFTR LoFTR论文链接&#xff1a;LoFTR LoFTR的提出&#xff0c;是将Transformer模型的注意力机制在特征匹配方向的应用&#xff0c;Transformer的提取特征的机制&#xff0c;在自身进行&#xff0c;本文提出可以的两张图像之间进行特征计算&#xff0c;非常适合进行特…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...