.NET 8 中 Android 资源生成的改进和变化

作者:Dean Ellis
排版:Alan Wang

随着 .NET 8 的发布,我们引入了一个新系统,用于生成访问 Android 资源的 C# 代码。 在 Xamarin.Android、.NET 6 和 .NET 7 中生成 Resource.designer.cs 文件的系统已经被弃用。 新系统生成一个名为 _Microsoft.Android.Resource.Designer 程序集。其中包含每个程序集的所有最终资源类。

什么是 Android 资源?

所有 Android 应用程序都包含一些用户界面资源。它们通常具有 XML 文件形式,包含用户界面布局、png 或 svg 文件形式的图像和图标以及包含样式和主题等内容的值。请参阅 Google 文档以深入了解 Android 资源。

Android构建过程的一部分是使用 android sdk 工具 aapt2 将这些资源编译成二进制形式。为了访问这些资源,android 公开了一个 API,它允许您传递一个整数 id 来检索资源。

SetContentView (2131492864);

作为 aapt2 构建过程的一部分,将生成文件 R.txt,其中包含从资源的“string”名称到 Id 的映射。例如,layout/Main.xml 可能映射到 id 2131492864。为了从 C# 访问此数据,我们需要一种在代码中公开这些数据的方法。这是由项目 $(RootNamespace) 中的 Resource 类处理的。我们从 R.txt 中获取值并将它们公开在这个类中。在 .NET 7 及之前版本的系统中,该类被写入 Resource.designer.cs 文件。它允许用户不需要硬编码 Id 就可以编写可维护的代码。所以上面的调用实际上看起来像这样:

SetContentView (Resource.Layout.Main);

Resource.Id.Main 将映射到 aapt2 生成的 Id。

为什么要制定这个新系统?

旧系统存在一些影响应用程序大小和启动性能的问题。在旧系统中,每个 Android 程序集都有自己的一组 Resource 类。所以我们实际上到处都有重复的代码。因此,如果您在项目中使用 AndroidX,则引用 AndroidX 的每个程序集都会有一个像下面的 Resource 设计器 Id 类:

public class Resource {public class Id {// aapt resource value: 0x7F0A0005public const int seekBar = 2131361797;// aapt resource value: 0x7F0A0006public const int menu = 2131361798;}
}

该代码将在每个库中重复。可能还有其他类,例如 Layout/Menu/Style,都包含这些重复的代码。

此外,每个 Resource 类都需要在运行时更新以获得正确的值。这是因为只有当我们构建最终应用程序并生成 R.txt 文件时,我们才知道每个资源的 Id。因此应用程序 Resource 类是唯一具有正确 Id 的类。

旧系统使用了名为 UpdateIdValues 的方法,该方法在启动时调用。该方法将遍历所有库项目并更新资源 Id 以匹配应用程序中的资源 Id。根据应用程序的尺寸,这可能会导致严重的启动延迟。下面是该方法中的代码示例:

public static void UpdateIdValues()
{global::Library.Resource.Id.seekBar = global::Foo.Foo.Resource.Id.seekBar;global::Library.Resource.Id.menu = global::Foo.Foo.Resource.Id.menu;
}

更糟糕的是,由于 UpdateIdValues 代码的存在,修剪器无法删除这些类中的任何一个。因此,即使应用程序只使用了一个或两个字段,所有这些类都会被保留

新系统对所有这些进行了重新设计,以使其适应修剪器,几乎以上显示的所有代码都不再生成。 ,甚至根本不需要 UpdateIdValues 调用。这将改善应用程序的大小和启动时间。

这个新系统是如何运作的?

默认情况下,.NET 8 Android 将 MSBuild 属性 $(AndroidUseDesignerAssembly) 设置为 true,完全关闭旧系统。重新启用旧系统需要手动将此属性更改为 false。

新系统依赖于解析 aapt2 在构建过程中生成的 R.txt 文件。在运行 C# 编译器之前,将解析 R.txt 文件并生成新的程序集。该程序集将保存在 IntermediateOutputPath 中,并且它会自动添加到应用程序或库的 References 列表中。

对于库项目,我们生成引用程序集而不是完整程序集。这向编译器发出信号,表明该程序集将在运行时被替换。(引用程序集是包含程序级 ReferenceAssemblyAttribute 的程序集。)
对于应用程序项目,我们生成完整的程序集作为 UpdateAndroidResources 目标的一部分。 这确保我们使用的是 R.txt 文件中的最终值。这个最终的程序集将使用最终的包进行部署。

除了程序集之外,还将生成源文件 __Microsoft.Android.Resource.Designer.cs,如果您使用 F#,源文件为 __Microsoft.Android.Resource.Designer.fs。它包含一个从 Resource 类派生的类。它将存在于项目的 $(RootNamespace) 中。这是使现有代码能够正常工作的纽带 。 因为 Resource 类的命名空间不会改变。对于应用程序项目,项目 RootNamespace 中的 Resource 类将从设计器程序集中的 ResourceConstants 类派生。这是为了保持与旧的Resource.designer.cs 文件在应用程序项目中的工作方式的向后兼容性 。

测试表明我们可以将启动时间缩短约 8%。整体封装尺寸大约减少 2%-4%。
在这里插入图片描述

我的 NuGet 包仍然有效吗?

有些人可能担心通过此更改,现有的包引用将停止工作。不用担心,新系统引入了一个修剪步骤,它将会升级旧系统的程序集引用以使用新系统。这将作为构建的一部分自动完成。此修剪步骤分析所有程序集中的 IL,查找使用旧 Resource.designer 字段的位置。然后,它将更新这些地方以使用新的Designer程序集属性。它还将完全删除该程序集中的旧Resource.designer。因此,即使您使用旧软件包,您仍然可以使用这个新系统。

链接器步骤应该涵盖访问 Resource.designer.cs 字段的几乎所有代码。但是,如果您遇到问题,请在 https://github.com/xamarin/xamarin-android/issues/new/choose 上提交问题。

这个功能将适用于 net8.0-android 之前的任何 Android 程序集引用。

使用新系统构建的包不能与以前版本的.NET Android 一起使用。如果您需要支持 .NET 7 或 Classic Xamarin.Android,请考虑使用多目标定位。

NuGet 包作者

如果您正在维护包含 Android 资源的 NuGet 包,如果是的话,您将需要进行一些更改。首先,不需要随 NuGet 一起提供新的 _Microsoft.Android.Resource.Designer.dll。它将由使用 NuGet 的应用程序在构建时生成。

新系统与 Classic Pre .NET Xamarin.Android 以及 .NET 6/7 Android 软件包不兼容。因此,如果您想继续支持 Classic Xamarin.Android 以及 .NET 8,您将需要对程序集进行多目标操作。如果您不再需要支持 Xamarin.Android 类,您可以将项目升级到 .NET Sdk Style 项目并使用以下内容:

<TargetFrameworks>net7.0-android;net8.0-android</TargetFrameworks>

Classic Xamarin.Android 将于明年停止支持,所以这可能是最佳选择。

如果您需要支持这两个系统,您可以使用 Xamarin.Legacy.Sdk 来同时支持 Xamarin.Android 和 net8.0-android。 Xamarin.Legacy.Sdk 是不受支持的,所以它只能作为用户升级到 .NET 8 时的权宜之计。有关如何使用此包的详细信息,请参阅 Xamarin.Legacy.Sdk GitHub 站点 https://github.com/xamarin/Xamarin.Legacy.Sdk。

从 .NET 6 android 开始,AndroidResource、AndroidAsset、AndroidEnvironment、AndroidJavaLibrary、EmbeddedNativeLibrary 和 AndroidNativeLibrary 项不再打包在程序集中。而是在构建时会生成一个 .aar 文件,其中包含这些数据,并命名为与程序集相同的名称。为了正常工作,需要将 .aar 文件与程序集一起发送到 NuGet 中。如果不包含 .aar,在运行时将会出现资源丢失错误,例如:

System.MissingMethodException: 'Method not found: int .Style.get_MyTheme()'

如果您在项目中使用 dotnet pack 并在 csproj 中指定 NuGet 属性和设置,则默认情况下会包含 .aar。但是,如果您使用 .nuspec,则需要手动将 .aar 文件添加到要包含的文件列表中。

与 .aar 文件和嵌入文件相关的更改在 OneDotNetEmbeddedResources.md 中有文档记录。

总结

因此,新系统会导致软件包大小略微缩小,并且启动时间更快。您在应用程序中使用的资源越多,影响就越大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/205913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

No Chromedriver found that can automate Chrome ‘x.x.xxxx‘的解决办法

一、前置说明 在使用Appium对Android设备自动化测试时&#xff0c;切换WebView时抛出异常&#xff1a; selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: No Chromedriver foun…

交叉验证以及scikit-learn实现

交叉验证 交叉验证既可以解决数据集的数据量不够大问题&#xff0c;也可以解决参数调优的问题。 主要有三种方式&#xff1a; 简单交叉验证&#xff08;HoldOut检验&#xff09;、k折交叉验证&#xff08;k-fold交叉验证&#xff09;、自助法。 本文仅针对k折交叉验证做详细解…

基于ssm vue个人需求和地域特色的外卖推荐系统源码和论文

首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计。本项…

利用管道、信号量、信号、共享内存和消息队列进行多进程通信

一.管道&#xff08;分为命名管道和匿名管道&#xff09; 管道的特点&#xff1a; ①无论是命名管道还是匿名管道&#xff0c;写入管道的数据都存放在内存之中。 ②管道是一种半双工的通信方式&#xff08;半双工是指终端A能发信号给终端B&#xff0c;终端B也能发信号给终端…

软件开发安全指南

2.1.应用系统架构安全设计要求 2.2.应用系统软件功能安全设计要求 2.3.应用系统存储安全设计要求 2.4.应用系统通讯安全设计要求 2.5.应用系统数据库安全设计要求 2.6.应用系统数据安全设计要求 软件开发全资料获取&#xff1a;点我获取

Linux 网络协议

1 网络基础 1.1 网络概念 网络是一组计算机或者网络设备通过有形的线缆或者无形的媒介如无线&#xff0c;连接起来&#xff0c;按照一定的规则&#xff0c;进行通讯的集合( 缺一不可 )。 5G的来临以及IPv6的不断普及&#xff0c;能够进行联网的设备将会是越来越多&#xff08…

vue 商品列表案例

my-tag 标签组件的封装 1. 创建组件 - 初始化 2. 实现功能 (1) 双击显示&#xff0c;并且自动聚焦 v-if v-else dbclick 操作 isEdit 自动聚焦&#xff1a; 1. $nextTick > $refs 获取到dom&#xff0c;进行focus获取焦点 2. 封装v-focus指令 (2) 失去焦点&#xff0c;隐藏…

用Rust刷LeetCode之66 加一

66. 加一[1] 难度: 简单 func plusOne(digits []int) []int { length : len(digits) // 从最低位开始遍历&#xff0c;逐位加一 for i : length - 1; i > 0; i-- { if digits[i] < 9 { digits[i] return digits } d…

【Mac】brew提示arch -arm64 brew以及uname返回x86_64的问题

背景 使用MacBook 14 M1 Pro两年了&#xff0c;自从使用了第三方Shell工具WindTerm后&#xff0c;使用brew时会提示我使用arch -arm64 brew安装&#xff0c;一开始没太在意&#xff0c;直到今天朋友问我uname -a返回的是什么架构&#xff0c;我才惊讶的发现竟然返回的是x86_64…

优化系统性能:深入性能测试的重要性与最佳实践

目录 引言 1. 为什么性能测试重要&#xff1f; 1.1 用户体验 1.2 系统稳定性 1.3 成本节约 1.4 品牌声誉 2. 性能测试的关键步骤 2.1 制定性能测试计划 2.2 确定性能测试类型 2.3 设计性能测试用例 2.4 配置性能测试环境 2.5 执行性能测试 2.6 分析和优化 2.7 回…

QT----Visual Studio打开.ui文件报错无法打开

问题 在我安装完qt后将它嵌入vs&#xff0c;后新建的文件无法打开ui文件 解决方法 右击ui文件打开方式,添加,程序找到你qt的安装目录里的designer.exe。点击确定再次双击就能够打开。

VMware提示:此虚拟机似乎正在使用中,取得该虚拟机的所有权失败错误的解决方案

当你遇到这个的时候是不是很疑惑&#xff0c;现在给你解决方案 step1: 先找到配置文件目录 D:\centOs7_mini\ 这里写成你的这个 step2: 在这个地方查找最后面是 .vmx.lck文件夹,然后进行修改、删除、移动都可以 step3: 去虚拟机那边重新启动就行

RabbitMQ-学习笔记(初识 RabbitMQ)

本篇文章学习于 bilibili黑马 的视频 (狗头保命) 同步通讯 & 异步通讯 (RabbitMQ 的前置知识) 同步通讯&#xff1a;类似打电话&#xff0c;只有对方接受了你发起的请求,双方才能进行通讯, 同一时刻你只能跟一个人打视频电话。异步通讯&#xff1a;类似发信息&#xff0c…

【mysql】下一行减去上一行数据、自增序列场景应用

背景 想获取if_yc为1连续账期数据 思路 获取所有if_yc为1的账期数据下一行减去上一行账期&#xff0c;如果为1则为连续&#xff0c;不等于1就为断档获取不等于1的最小账期&#xff0c;就是离当前账期最近连续账期 代码 以下为mysql语法&#xff1a; select acct_month f…

查看Linux的Ubuntu的版本

我的Ubuntu版本是 Jammy x86_64&#xff0c;即 Ubuntu 22.04.3 LTS&#xff0c;代号为"Jammy Jellyfish"&#xff0c;架构是 x86_64&#xff08;64位&#xff09;。

NLP自然语言处理学习笔记

参考&#xff1a;NLP&#xff08;自然语言处理&#xff09;介绍 - 知乎 (zhihu.com) 一、NLP是什么 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自…

最新版本——Hadoop3.3.6单机版完全部署指南

大家好&#xff0c;我是独孤风&#xff0c;大数据流动的作者。 本文基于最新的 Hadoop 3.3.6 的版本编写&#xff0c;带大家通过单机版充分了解 Apache Hadoop 的使用。本文更强调实践&#xff0c;实践是大数据学习的重要环节&#xff0c;也能在实践中对该技术有更深的理解&…

105.长度最小的子数组(力扣)|滑动窗口

代码演示 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int result INT_MAX; // 用于存储最小子数组的长度int sum 0; // 滑动窗口的长度int i 0; // 滑动窗口的起始位置int sumlength 0; // 当前子数…

深度学习与逻辑回归模型的融合--TensorFlow多元分类的高级应用

手写数字识别 文章目录 手写数字识别1、线性回归VS逻辑回归Sigmoid函数 2、逻辑回归的基本模型-神经网络模型3、多元分类基本模型4、TensorFlow实战解决手写数字识别问题准备数据集数据集划分 特征数据归一化归一化方法归一化场景 标签数据独热编码One-Hot编码构建模型损失函数…

探索人工智能领域——每日20个名词详解【day11】

目录 前言 正文 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x1f4e3;如需转载&#xff0c;请事先与我联系以…