Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

android - Can someone actually explain the workings of Resource.Designer.cs?

I routinely have problems during project builds where Resource.Designer gets generated but will no longer compile. My search engine shows that I'm not the only one that has this problem, but I've also not found any reliable "fix" for when it happens.

For example, right now I have a project that works just fine, but if I add a reference to a NuGet library (that I created) then the app will no longer compile because of loads of errors in Resource.Designer.cs.

On another project, I simply upgraded Xamarin Forms and now I can no longer compile, again due to a load of errors in Resource.Designer.cs.

Of course the immediate issue is "how do I fix the errors in these projects" but really I want to understand what is fundamentally going on here. What causes Resource.Designer to get generated and regenerated? What algorithm is used to decide what items get put into that file? Why do we so often end up with a file getting generated that then cannot actually compile? Why is it not getting the references it needs for those items?

I'd really like to understand this at a fundamental level so that once I get past the current thing causing me headaches, I can avoid it in the future when it comes up again (and I most certainly will come up again).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Resource.Designer.cs is synonymous with R.java in Android. Which of course is an application's resources that are referred to by a generated constant Resource ID.

These items are usually defined in your Xamarin.Android's .csproj via:

<AndroidResgenClass>Resource</AndroidResgenClass> (This might be outdated)

or

<AndroidResgenFile>ResourcesResource.Designer.cs</AndroidResgenFile> (Current)

This is part of the Android Build process in which the aapt tooling will generate respective constant resource IDs per each resource defined in your project(res/ - Android, Resources/ - Xamarin.Android). These are then processed into binary form and embedded into the .apk. Thus the Resource.designer.cs is generated after a successful aapt.

It then goes a bit further to define a Resource in a specific Resource Type:

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

  • anim
  • animator
  • array
  • attr
  • bool
  • color
  • dimen
  • drawable
  • fraction
  • id
  • integer
  • interpolator
  • layout
  • menu
  • mipmap
  • plurals
  • raw
  • string
  • style
  • styleable
  • transition
  • xml

Since aapt is called in the Android Build tooling, it is highly recommended to not manually invoke it unless you understand the complete Android build process.

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

As far as an "Algorithm", I don't think it's really that complex other than simply mapping a Resource ID to a resource as defined above. There are some complexities in the sense of Merging Resources in a project. For example a library project -> your application project:

The build tools merge resources from a library module with those of a dependent app module. If a given resource ID is defined in both modules, the resource from the app is used.|

If conflicts occur between multiple AAR libraries, then the resource from the library listed first in the dependencies list (toward the top of the dependencies block) is used.

To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the module (or is unique across all project modules).

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

Given the majority of people's issues with Resource.designer.cs, they typically come from a point of view of understanding where actual third-party Resources come from and how they are supported. Here are some tips that I personally use:

  1. Ensure your Application project is compiled against the latest API version. Typically this will be the <TargetFrameworkVersion> MSBuild property. One of my colleagues has an amazing blog post that stands the test of time about this factor:

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

  1. Find where the Resource is coming from. Does it come from an official NuGet package? When was the Resource introduced into the Android framework? (Useful for mostly Material Design items).

For example, if I had an error message regarding colorPrimary, I might check what API it was introduced in:

Added in API level 21

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

Thus we now know we require API 21+ at minimum to use this item.

  1. Take a deep dive into the dependencies you are loading into your project. You can use a decompiler like dotPeek to look through an assembly and see what Resources it's trying to give your project. Additionally you can look at the cache of respective .aar and view it's res/ folder. This is mostly useful for larger bindings like the Android Support / Google Play Services ones. For smaller projects, look for the /res string inside the decompiled .dll

For example let's take a look at com.android.support:appcompat-v7:24.2.1:

First we need to find the cache on our machine:

AppDataLocalXamarinXamarin.Android.Support.v7.AppCompat24.2.1embedded es (If you get stuck here on OSX, I wrote a guide awhile back about finding these paths here - https://developer.xamarin.com/guides/android/troubleshooting/resolving-library-installation-errors/)

So we can now look through all of the respective Resources this library is trying to give to us.

  1. Finally the last item is that people tend to delete the Resource.designer.cs file from their project. After the aapt process is complete, it will generate a new one or it will fail on aapt. It is up to you to figure out whether that step passed or not (i.e. Check the main project Resources folder for the newly generated Resource.designer.cs file so you can re-include it into your project).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...