【问题标题】:Can someone actually explain the workings of Resource.Designer.cs?有人可以真正解释 Resource.Designer.cs 的工作原理吗?
【发布时间】:2016-11-06 16:35:44
【问题描述】:

在生成 Resource.Designer 但不再编译的项目构建期间,我经常遇到问题。我的搜索引擎显示我不是唯一一个遇到此问题的人,但我也没有找到任何可靠的“修复”来解决它何时发生。

例如,现在我有一个工作正常的项目,但如果我添加对 NuGet 库(我创建的)的引用,那么应用程序将不再编译,因为 Resource.Designer.cs 中存在大量错误.

在另一个项目中,我只是升级了 Xamarin Forms,但现在我无法再编译,这又是由于 Resource.Designer.cs 中的大量错误。

当然,最直接的问题是“我如何修复这些项目中的错误”,但我真的想了解这里的基本情况。是什么导致 Resource.Designer 生成和重新生成?使用什么算法来决定将哪些项目放入该文件中?为什么我们经常会生成一个无法实际编译的文件?为什么它没有获得这些项目所需的参考资料?

我真的很想从根本上理解这一点,这样一旦我克服了当前导致我头痛的事情,我就可以在将来再次出现时避免它(而且我肯定会再次出现) .

【问题讨论】:

    标签: android xamarin xamarin.android aapt


    【解决方案1】:

    Resource.Designer.cs 与 Android 中的 R.java 同义。这当然是由生成的常量Resource ID 引用的应用程序资源。

    这些项目通常在您的Xamarin.Android.csproj 中通过以下方式定义:

    <AndroidResgenClass>Resource</AndroidResgenClass>(这可能已经过时了)

    <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>(当前)

    这是Android Build 过程的一部分,其中aapt 工具将为您项目中定义的每个资源生成相应的常量资源ID(res/ - Android,Resources/ - Xamarin.Android)。然后将它们处理成二进制形式并嵌入到.apk 中。因此Resource.designer.cs 是在成功的aapt 之后生成的。

    然后在特定的Resource Type: 中定义一个Resource

    http://code.google.com/android/reference/android/R.html

    • 动画
    • 动画师
    • 数组
    • 属性
    • 布尔
    • 颜色
    • 尺寸
    • 可绘制
    • 分数
    • 身份证
    • 整数
    • 插值器
    • 布局
    • 菜单
    • mipmap
    • 复数
    • 原始
    • 字符串
    • 风格
    • 样式化
    • 过渡
    • xml

    由于 aapt 在 Android 构建工具中被调用,因此强烈建议不要手动调用它,除非您了解完整的 Android 构建过程。

    https://developer.android.com/studio/command-line/index.html

    就“算法”而言,除了简单地将Resource ID 映射到上面定义的资源之外,我认为它并没有那么复杂。在项目中Merging Resources 存在一些复杂性。 例如一个库项目 -> 你的应用项目:

    构建工具将库模块的资源与依赖应用模块的资源合并。如果在两个模块中都定义了给定的资源 ID,则使用来自应用程序的资源。|

    如果多个 AAR 库之间发生冲突,则使用依赖项列表中第一个列出的库中的资源(靠近依赖项块的顶部)。

    为避免公共资源 ID 的资源冲突,请考虑使用对模块唯一(或在所有项目模块中唯一)的前缀或其他一致的命名方案。

    https://developer.android.com/studio/projects/android-library.html#Considerations

    鉴于大多数人对Resource.designer.cs 的问题,他们通常从了解实际第三方Resources 来自何处以及如何支持它们的角度出发。以下是我个人使用的一些技巧:

    1. 确保您的应用程序项目是根据最新的 API 版本编译的。通常这将是<TargetFrameworkVersion> MSBuild 属性。我的一位同事发表了一篇精彩的博文,经得起时间的考验:

    http://redth.codes/such-android-api-levels-much-confuse-wow/

    1. 查找Resource 的来源。它来自官方的 NuGet 包吗? Resource 是什么时候引入 Android 框架的? (主要用于 Material Design 项目)。

    例如,如果我有一条关于 colorPrimary 的错误消息,我可能会检查它是在什么 API 中引入的:

    在 API 级别 21 中添加

    https://developer.android.com/reference/android/R.attr.html#colorPrimary

    因此我们现在知道我们至少需要 API 21+ 才能使用此项目。

    1. 深入了解要加载到项目中的依赖项。您可以使用像 dotPeek 这样的反编译器来查看程序集并查看 Resources 它试图为您的项目提供什么。此外,您可以查看各个.aarcache 并查看它的res/ 文件夹。这对于像 Android Support / Google Play Services 这样的较大绑定非常有用。对于较小的项目,在反编译的.dll 中查找/res 字符串

    例如让我们看看com.android.support:appcompat-v7:24.2.1

    首先我们需要在我们的机器上找到缓存:

    AppData\Local\Xamarin\Xamarin.Android.Support.v7.AppCompat\24.2.1\embedded\res(如果你在 OSX 上卡住了,我不久前写了一篇关于在这里找到这些路径的指南 - https://developer.xamarin.com/guides/android/troubleshooting/resolving-library-installation-errors/

    所以我们现在可以查看该库试图提供给我们的所有 Resources

    1. 最后一项是人们倾向于从他们的项目中删除Resource.designer.cs 文件。在aapt 进程完成后,它将生成一个新进程,否则将在aapt 上失败。由您决定该步骤是否通过(即检查主项目 Resources 文件夹以获取新生成的 Resource.designer.cs 文件,以便您可以将其重新包含到您的项目中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-11
      • 2016-09-11
      • 1970-01-01
      • 2021-08-02
      • 2012-02-14
      • 2014-11-28
      • 1970-01-01
      • 2020-06-16
      相关资源
      最近更新 更多