Android资源管理中的SharedLibrary和Dynamic Reference-------之资源共享库(一)

2023-11-19

一.引言

    共享库的概念,相信大家都有所了解,它有有许多优点。可以设想,在一个系统上要跑100个应用,并且它们都使用到了同一个库。如果这个库做成静态库,那么每个应用中都要打包一次这个库,100个应用就是100次,这无疑是重复的。我们可不可以在系统里只集成一次这个库呢,每个应用用到的时候再动态加载与链接,动态库的概念就这么产生了。现在,PC上Linux、Windows、Mac中动态库的应用已经非常广泛了。当然,Android中的动态库的应用也非常多,写JNI的同学都非常熟悉了。

    不过,我们今天讨论的动态库,指的并不是这些。我们知道一个APK中简单来说主要包括两部分:代码(DEX和so等)和资源(Asset、XML和Raw等)。前面我们 讲的动态库的概念主要是针对代码而言的,那么资源呢?我们可不可以动态加载和使用资源呢?答案当然是OK,毕竟现在已经有各种资源动态加载的框架了。但我们今天说的也不是这些框架,而是Android本身支不支持资源的动态加载呢?

二.framework-res.apk

    我们知道,Android本身也有很多资源,想必大家对这些代码都比较熟悉吧:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

    没错,这就是我们新建一个Android Project的时候,IDE自动为我们生成的一个Theme。这个Theme就继承了Android本身的一个Theme:Theme.Material.Light.DarkActionBar。那么问题来了,Android的这个Theme是编译的时候IDE把它打包到我们的每一个APK里面去;还是说,这个Theme(当然也包括其它系统资源)只在系统中存在一份,我们的应用运行时,去系统加载呢?答案当然是后者,这是不是跟so库的动态加载有些类似了呢(补充,一般我们也会将so库打包到APK中,但如果系统中有对应的so库的时候,我们可以不用打包进去的)?

    其实,从应用的角度看,Android的framework包括两部分:java代码和资源。java代码比如我们用到的四大组件、各种控件等等,它们被打包成framework.jar,放在/system/framework/下面;资源则包括了系统的drawable、style、string等等,它们被打包成了framework-res.apk,也放在/system/framework/下面,前面说的Theme.Material.Light.DarkActionBar就存在于framework-res.apk。需要说明的是,别看framework-res.apk是一个APK,但它里面没有dex字节码,全部都是资源,完完全全的一个资源库。和so库的不同也就是它里面装的是资源,而so库里是本地机器码。当我们的应用起来后,在makeApplication的时候,就会去加载这个资源包,然后我们就可以使用Android提供的各种资源了。至于系统是怎么加载这个资源包的,我们后面会专门讨论,这里就不做详细介绍了。

三.ApplicationInfo.sharedLibraryFiles

    通过对系统的资源包framework-res.apk的分析,我们至少知道,Android中对资源是有着和共享库类似的加载机制的,但这种机制能不能拓展开来呢?设想一下,我们也可以做一个资源包,然后把它放到系统里面去,然后我们的各个应用不用每个都打包一次这些资源,大家共用这一套。

    当然,可以了,而且,Android也提供了支持,只是大家很少去关注罢了。OK,那么现在就让我们一起去扒一扒吧。ApplicationIfo这个类大家应该有用到吧,大家有没有注意到它内部的这些代码:

在这里插入图片描述

大家看着注释,能说出这些变量都是干什么用的吗?特别是

public String sourceDir;

public String[] resourceDirs;

public String[] sharedLibraryFiles;

public String nativeLibraryDir;

这四个变量。

public String sourceDir;//如果APK不分片的话,就是我们的APK在系统中的路径

public String[] resourceDirs;//这个是overlay Package的路径,可以有多个overlay package。overlay package的概念我们后面也会专门讨论。

public String nativeLibraryDir;;//这个就是我们的so库的路径了

    那么大家肯定会有疑问,public String[] sharedLibraryFiles;这个变量呢,sharedLibraryFiles应该也是共享库的路径吧。是的,这个是共享库的路径,但不是so库的路径。这里的共享库,指的就是我们前面所说的资源共享库。也就是说Android是支持资源共享库这个概念的。

四.uses-library

     Android Framework既然有了资源共享库(我们姑且这么叫吧)的机制,那么会不会顺手给应用层一个接口呢,这样多方便呀,而且也不用多大工作量,这个真的可以有_

别说,这个还真的有。大家对AndroidManifest.xml都非常熟悉,它里面有许多标签,比如Application、Activity、Service等等,其中有一个标签叫做uses-library,就是来引入资源共享库的:

在这里插入图片描述

     这个是Android Framework中的一个project,路径为frameworks/base/tests/SharedLibrary/client/AndroidManifest.xml,我们看看其中的一个layout文件:

在这里插入图片描述

它分别引用了lib资源包里的string、style、drawable资源。当然,我们也可以换个姿势,在java文件里,通过R文件引用:

在这里插入图片描述

String[] animals = getResources().getStringArray(com.google.android.test.shared_library.R.array.animals);

这行妥妥的。

我们再来看一下被引用的库,其路径为frameworks/base/tests/SharedLibrary/lib/AndroidManifest.xml
在这里插入图片描述

这行声明 ”我是一个资源共享库“。

这个资源共享库APK和一般的APK有个区别,它的values目录下多了一个public.xml文件,并且这个public文件里的资源的包id是0x00而不是我们熟悉的0x7f(啰嗦一句,资源id的各个位的意义是:0xpptteeee,pp表示包id,占8位;tt表示type id,占8位;eeee表示entry id,占16位。package就不说了,type是指资源类型,比如drawable、color等;entry则表示资源的名称,这个后面介绍AssetManager的时候会详说):
在这里插入图片描述

做framework的同学应该非常清楚public.xml的作用,就是向别的应用export资源的。

另外,这个资源库的Android.mk也要注意,它和一般的应用不同,多了一个aapt flag: LOCAL_AAPT_FLAGS := --shared-lib

在这里插入图片描述

其实,也正是LOCAL_AAPT_FLAGS := --shared-lib,使得aapt在编译资源时,会给它的包id指定为0x00.

五.关于aar

    这种资源共享库的概念和aar相比,有何异同呢,我总结了一下:

    1. aar是资源的静态库,它里面的资源是打包到我们每一个应用里面去的,而资源共享库是一个独立的包,这是最本质的区别。

    2.aar里的资源是没有编译过的,所以它没有包名。假设我们的应用是com.demo.app,那么我们在java文件里引用aar里的资源可以用com.demo.app.R.xx.xxxx,在xml里引用aar的资源和引用自己应用的资源方式没有什么不同;但是资源共享库里的资源是编译过的,也是有包名的,因此它在java中和xml中的引用方式和我们对自己应用里的资源引用方式不太一样,如上面的图中。从这一点来说,确实aar用起来更方便。

    3.资源共享库是一个单独的包,需要安装或者放到特定目录或者需要特定的系统配置,aar则没有这个限制。这一点也是资源共享库大多用在手机厂商的系统应用中,而没能在App中广泛应用的最大原因。

    4.aar作为一种静态资源库,自然会出现不同应用重复集成的问题,这是所有静态库共同的的缺点,而资源共享库则没有这个 问题。

    5.aar库的依赖更强,库本身的集成、升级、维护比较麻烦。设想资源共享库自己更新一个版本,所有引用这个共享库的App无需任何改动就可以生效,活脱脱的热修复、模块化,哈哈,说得有些牵强了。但aar的更新就麻烦得多了,你要对所有使用这个aar的应用做修改、编译、打包、发布。

    现在,我们从应用层面介绍了Android的资源共享库的概念,大家对着代码看一下就会用了,非常简单,后面我们将从framework、aapt、AssetManager三个方面来介绍其实现原理,敬请期待

原文链接:https://blog.csdn.net/dayong198866/article/details/95226237

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android资源管理中的SharedLibrary和Dynamic Reference-------之资源共享库(一) 的相关文章

随机推荐

  • 【前端知识点总结】Vue(一) 脚手架 及 ESlint

    Vue 前端攻城狮必备技能 1 什么是 Vue 渐进式 javacript 框架 渐进式 按需添加功能 逐渐集成 框架 拥有自己的语法规则 例 Vue 项目对其依赖很高 业务开发中如果选择了框架最好不要轻易更换框架 否则需要重构的地方很多
  • 软件版本详细对比alpha,beta,Gamma,RC,RT

    开源软件发布的时候 经常有alpha beta RC1 RC2 RC3等等 看得云里雾里 不知道啥意思 做了个简单总结 缩写 全称 中文意思 详细说明 功能与bug alpha 内测 开发团队内部测试的版本或者有限用户体验测试版本 功能不全
  • SylixOS IDE工具使用

    1 问题描述 使用RealEvo IDE 以下简称IDE 开发程序时 误操作输入错误的函数名称时 编译器不会报错 输入错误的函数名示例代码如程序清单1 1所示 程序清单 1 1 示例代码 include
  • 软件自动化测试对软件产品起到什么作用?有什么注意事项?

    自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程 通常 在设计了测试用例并通过评审之后 由测试人员根据测试用例中描述的规程一步步执行测试 得到实际结果与期望结果的比较 一 软件自动化测试的作用 1 提高测试效率 自动化测试可以大幅
  • 小记MAC安装GIT

    MAC安装GIT教程 0 安装方式说明 MAC安装软件的时候 有一个很好用的工具 叫 homebrew 大家可以试一下 我这里采用下载安装包的方式进行 1 下载git 我这里就暂且选择git最新版本 2 36 1 正常情况下 我们一般不选择
  • 经典的笔试题解析《高质量C/C++编程》

    对于 高质量C C 编程 想必这个已经是早已成名的经典书籍了 在此 笔者借用两三个题目 解析下面代码 错误示列 请勿模仿 正确的代码 在后面部分 include
  • 快排 + 二分

    一直觉得快排跟二分很像 大家也都有很多变种 在此整理一下 快排的特点是 需要一个pivort 让左边比他大 右边比他小 反之亦然 每次排序都有一个数的位置被确定 两种写法其实是一种 经典partition写在一个函数里 class Solu
  • Flutter BottomNavigationBar组件(底部导航栏)

    Flutter BottomNavigationBar 组件 BottomNavigationBar 常见的属性 属性名 说明 items List 底部导航条按钮集合 页面集合 iconSize icon currentIndex 默认选
  • 单相逆变器第二课、DC/AC电路基础理论学习

    这周是真心忙 到现在才把DC AC单相部分的理论知识看完 但由于是第一次接触电力电子 写的不好的地方 大家轻喷 DC AC变换电路成为逆变 也就是直流电压 电流 向交流电压 电流 变化 先来看下电压型逆变器 电压型逆变器主要有三类 电阻负载
  • 90 后学霸博士 8 年进击战:用机器学习为化工研究叠 BUFF

    本文首发自微信公众号 HyperAI超神经 内容一览 ScienceAI 作为近两年的技术热点 引起了业界广泛关注和讨论 本文将围绕 ScienceAdvances 的一篇论文 介绍如何利用机器学习 对燃煤电厂的胺排放量进行预测 关键词 A
  • 简短的 mouseover 显示与隐藏层的办法

    简短的 mouseover 显示与隐藏层的办法 在制作 mouseover 和 mouseout 显示 隐藏层的时候 有时总会出现 mouseover 层里面的对象时 层消失的情况 这是因为mouseover 层内 对象时 会对前层产生两个
  • 从零开始学习OpenWrt完美教程

    Cisco Linksys在2003年发布了WRT54G这款无线路由器 同年有人发现它的IOS是基于Linux的 然而Linux是基于GPL许可证发布的 按照该许可证Cisco应该把WRT54G 的IOS的源代码公开 2003年3月 Cis
  • ASP.NET Core项目无法使用命令行执行ef命令

    在项目目录下 打开命令行窗口 执行dotnet ef help 提示以下信息 报错信息 无法执行 因为找不到指定的命令或文件 可能的原因包括 你拼错了内置的 dotnet 命令 你打算执行 NET Core 程序 但 dotnet ef 不
  • mv:重命名和移动文件、文件夹

    在Linux中 mv命令可以用于重命名和移动文件 也可以用于重命名和移动文件夹 注意 如果目标目录已经存在同名的文件或文件夹 mv命令将覆盖目标文件或合并目标文件夹 请注意 在使用mv命令时要小心 确保提供正确的文件名和路径 以免误操作造成
  • 这样的程序员年薪可以达到多少呢?

    转载于 https www cnblogs com Rainbow890722 p 10456640 html
  • 美媒体称谷歌卫星技术可实时定位全球军舰

    5月17日 美国 AOL防务 网站刊登文章 称谷歌公司将推出一款新软件 可让用户对任何一艘海上船只进行实时追踪定位并了解水深数据 包括美海军军舰 做了美军做不到的事 据悉 谷歌公司耗资数百万美元发展能够精确定位船只方位并搜集水深数据的卫星技
  • Redis 跳跃表

    跳跃表 跳跃表基础知识 跳跃表 网易公开课 gt 跳跃表 总结 效率堪比各种平衡树结构 如红黑树 B树 B 树 实现起来简单 仅用到链表的知识 基于概率论 有个随机过程 但表现不错
  • 神经网络优化(损失函数:自定义损失函数、交叉熵、softmax())

    参考 神经网络优化 损失函数 自定义损失函数 交叉熵 softmax 云 社区 腾讯云 1 前向传播 搭建网络结构 反向传播 训练网络参数 2 激活函数 提高了模型的表达里 使模型更具有表达力 3 神经网络的层数 通常用神经网络的层数和神经
  • 区块链应用技术学习(一)

    众所周知 区块链技术的特性就在于其去中心化与不可篡改性 由于这俩点的特性的存在 使得区块链技术的发展颇有看头 于是小编我也踏上了区块链学习的过程 文章目录 前言 一 区块链是什么 二 区块链作用 1 企业 2 个人 总结 前言 在学习区块链
  • Android资源管理中的SharedLibrary和Dynamic Reference-------之资源共享库(一)

    一 引言 共享库的概念 相信大家都有所了解 它有有许多优点 可以设想 在一个系统上要跑100个应用 并且它们都使用到了同一个库 如果这个库做成静态库 那么每个应用中都要打包一次这个库 100个应用就是100次 这无疑是重复的 我们可不可以在