.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.rhkb.cn/news/212388.html

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

相关文章

苍穹外卖+git开源

搁置了很久重新开始学 为了学习方便&#xff0c;苍穹外卖的前后端代码已放至git开源。前端源代码请看给i他-->sky-take-out: 苍穹外卖 git学习-->Git基础使用-CSDN博客 后端接口员工管理和分类管理模块 添加员工&#xff0c;添加的表单账号、手机号、身份证都…

Spring Boot的日志

打印日志 打印日志的步骤: • 在程序中得到日志对象. • 使用日志对象输出要打印的内容 在程序中得到日志对象 在程序中获取日志对象需要使用日志工厂LoggerFactory,代码如下: package com.example.demo;import org.slf4j.Logger; import org.slf4j.LoggerFactory;public c…

安装you-get(mac)

1、首先要有python环境 2、更新pip python -m pip install --upgrade pip 3、安装you-get pip install you-get;

T天池SQL训练营(五)-窗口函数等

–天池龙珠计划SQL训练营 5.1窗口函数 5.1.1窗口函数概念及基本的使用方法 窗口函数也称为OLAP函数。OLAP 是OnLine AnalyticalProcessing 的简称&#xff0c;意思是对数据库数据进行实时分析处理。 为了便于理解&#xff0c;称之为窗口函数。常规的SELECT语句都是对整张表进…

创建vue项目:node.js下载安装、配置环境变量,下载安装cnpm,配置npm的目录、镜像,安装vue、搭建vue项目开发环境(保姆级教程一)

今天讲解 Windows 如何创建 vue 项目&#xff0c;搭建 vue 开发环境&#xff0c;这是这个系列的第一章&#xff0c;有什么问题请留言&#xff0c;请点赞收藏&#xff01;&#xff01;&#xff01; 文章目录 一、Vue简单介绍二、开始搭建1、安装node.js环境2、配置npm下载时的默…

一文3000字从0到1用Python进行gRPC接口测试!

gRPC 是一个高性能、通用的开源RPC框架&#xff0c;其由 Google 主要面向移动应用开发并基于HTTP/2 协议标准而设计&#xff0c;基于 ProtoBuf(Protocol Buffers) 序列化协议开发&#xff0c;且支持众多开发语言。 自gRPC推出以来&#xff0c;已经广泛应用于各种服务之中。在测…

数据可视化免费化的双面影响探析

近年来数据可视化的免费化也越来越明显&#xff0c;今天就以我作为可视化设计师的经验来和大家分析一下&#xff0c;数据可视化工具免费化所带来的利与弊。 先从好处入手&#xff0c;最明显的就是免费化可以让数据可视化工具得到更广泛的使用。 免费数据可视化工具使得更多人可…

docker搭建nginx实现负载均衡

docker搭建nginx实现负载均衡 安装nginx 查询安装 [rootlocalhost ~]# docker search nginx [rootlocalhost ~]# docker pull nginx准备 创建一个空的nginx文件夹里面在创建一个nginx.conf文件和conf.d文件夹 运行映射之前创建的文件夹 端口&#xff1a;8075映射80 docker…

电脑版便签软件怎么设置在桌面上显示?

对于不少上班族来说&#xff0c;如果想要在使用电脑办公的时候&#xff0c;随手记录一些常用的工作资料、工作注意事项等内容&#xff0c;直接在电脑上使用便签软件记录是比较方便的。电脑桌面便签工具不仅方便我们随时记录各类工作事项&#xff0c;而且支持我们快速便捷使用这…

长城之上的无人机:文化遗产的守护者

长城之上的无人机&#xff1a;文化遗产的守护者 在八达岭长城景区&#xff0c;两架无人机分别部署在了长城的南、北楼两点。根据当前的保护焦点和需求&#xff0c;制定了5条无人机综合巡查航线&#xff0c;以确保长城景区的所有开放区域都能得到有效监管。每天&#xff0c;无人…

Elasticsearch 8.9 flush刷新缓存中的数据到磁盘源码

一、相关API的handler1、接收HTTP请求的hander2、每一个数据节点(node)执行分片刷新的action是TransportShardFlushAction 二、对indexShard执行刷新请求1、首先获取读锁&#xff0c;再获取刷新锁&#xff0c;如果获取不到根据参数决定是否直接返回还是等待2、在刷新之后transl…

Java的三种代理模式实现

代理模式的定义&#xff1a; Provide a surrogate or placeholder for another object to control access to it.&#xff08;为其他对象提供一种代理以控制对这个对象的访问。&#xff09; 简单说&#xff0c;就是设置一个中间代理来控制访问原目标对象&#xff0c;达到增强原…

ProEasy机器人案例:电池边包胶

如下图所示&#xff0c;对一个电池三边包边&#xff0c;因客户现场有很多规格电池的大小&#xff0c;所以就需要建立动态的工具坐标来实现适配所有种类的电池 程序如下&#xff1a;Ddome程序 function Speed(num) --速度设置 MaxSpdL(2000) --movl最大速度…

茄子科技张韶全:跨多云大数据平台DataCake在OceanBase的实践

11 月 16 日&#xff0c;OceanBase 在北京顺利举办 2023 年度发布会&#xff0c;正式宣布&#xff1a;将持续践行“一体化”产品战略&#xff0c;为关键业务负载打造一体化数据库。其中&#xff0c;在“数字化转型升级实践专场”&#xff0c;我们有幸邀请到了茄子科技大数据技术…

数据库:JDBC编程

专栏目录 MySQL基本操作-CSDN博客 MySQL基本操作-CSDN博客 数据库的增删查改&#xff08;CRUD&#xff09;基础版-CSDN博客 数据库增删改查&#xff08;CRUD&#xff09;进阶版-CSDN博客 数据库的索引-CSDN博客 基本概念 JDBC编程就是通过Java代码来操作数据库 api 数据库是…

Apache+mod_jk模块代理Tomcat容器

一、背景介绍 最近在看Tomcat运行架构原理, 正好遇到了AJP协议(Apache JServ Protocol). 顺道来研究下这个AJP协议和具体使用方法. 百度百科是这么描述AJP协议的: AJP&#xff08;Apache JServ Protocol&#xff09;是定向包协议。因为性能原因&#xff0c;使用二进制格式来传输…

postcss-pxtorem实现页面自适应的原理

先声明一点这玩意本身不能实现哈&#xff0c;他只是一个工具&#xff0c;更是一个postcss的插件 帮助我们从px转化成为rem比如我们的代码 div {height: 100px;width: 100px; }经过这个插件转化之后变成 假设变成下面这样哈 div {height: 1rem;width: 1rem; }其他没啥子太大作…

2023年江西省“振兴杯”网络信息行业职业技能竞赛 Web4 Writeup

这次振兴杯碰到的一道题&#xff0c;某些姿势之前貌似没有碰过&#xff0c;简单记一下吧 源码 <?php class Bird{public $funcs;public $salt;public $flag;function say_flag(){$secret hash_hmac(sha256, $_GET[salt], file_get_contents(/flag));$hmac hash_hmac(sha…

企业软件的分类有哪些|app小程序定制开发

企业软件的分类有哪些|app小程序定制开发 企业软件是指为了满足企业运营和管理需求而开发的软件系统。根据不同的功能和应用领域&#xff0c;企业软件可以分为以下几个分类&#xff1a; 1. 企业资源计划&#xff08;Enterprise Resource Planning&#xff0c;ERP&#xff09;软…

【UE5】瞬移+马赛克过渡效果

效果 步骤 1. 新建一个工程&#xff0c;创建一个Basic关卡 2. 添加第三人称游戏资源到内容浏览器 3. 新建一个材质&#xff0c;这里命名为“M_Pixel” 打开“M_Pixel”&#xff0c;设置材质域为“后期处理” 在材质图表中添加如下节点 此时效果如下&#xff0c;已经有马赛克的…