I've been trying to figure out some weird issues around shared libraries and resources and am at a bit of a loss if it's perhaps just not supported?
I probably should start with a brief background -- we have a bunch of old C# apps on Windows Mobile 6.5 which we decided to port to Xamarin Android as the best path forward - lots of code reuse, etc. They were set up so some things (like the login screen, customer details screen, etc) were in separate .DLLs and you'd just add a references to whichever you needed.
When we ported the first app to Android we just got it working by adding all that shared code into the project... which works fine, but now we've finished the first port and starting working on the second we don't want to have to add the same shared code files into the next project.
So we've done a lift and shift - moved the shared components to a new DLL along with the .axml resources and at first blush it looks like it's all fine... the login screen still comes up (in both apps) and you can log in. So we continued along this path and did another component, and another and it looked like it was all fine until we started getting some weird crashes, specifically "An item with the same key has already been added."
The repro would be something akin to:
1) Go to a new sale
2) Go to product lookup -> crash "An item with the same key has already been added."
or
1) Go to product lookup
2) Go to a new sale -> crash "An item with the same key has already been added."
(you could use one or other, not both)
So I started digging around and I'm only guessing here but the Resources.Designer.cs for the library had some resources using the same (integer) id that was also used (for a different resource) in the App.
Thus begun a bunch of google-fu which drew me to the conclusion that the aapt generates these ids automatically 'per application', and that everything was considered an application by default and I probably should be passing the arg --shared-lib to aapt so that the library ids weren't going to cause a conflict with the apps ids. To do so, I added the following to the csproj of my library:
<AndroidResgenExtraArgs> -v --shared-lib </AndroidResgenExtraArgs>
This generates a slightly different R.java file (no 0x7f prefix from aapt and no 'static final', just 'static'):
public static final int txtProductStats=0x7f07010d; // this is an example id inside R.java when using default aapt settings
public static int txtProductStats=0x0007010d; // this is an example id inside R.java when using --shared-lib
R.java also has a new method: public static void onResourcesLoaded(int packageId) which seems to do an update to that id, eg:
id.txtProductStats = (id.txtProductStats & 0x00ffffff) | (packageId << 24);
None of this seems to be coming through to the Resources.Designer.cs file that's generated - it's basically empty, just a bunch of partial classes with no ids anywhere, so I'm wondering if --shared-lib is not supported by Xamarin? I couldn't find anything really either way, hence asking the question.
Is anyone else doing android shared libraries this way?
Has anyone had issues with duplicate ids causing crashes?
Is there a better way to do it?
Should we look at making these proper Xamarin components instead of a shared .DLL we just reference?
#ClutchingAtStraws