Xamarin.AndroidでUpperCamelCaseなリソースが見つからないときの解決法

このエントリーをはてなブックマークに追加

事の発端

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@color/IconLauncherBackground"/>
    <foreground android:drawable="@mipmap/IconLauncherForeground"/>
</adaptive-icon>

Xamarin.Androidでこんな感じに配置したリソースがmipmap-anydpi-v26/IconLauncher.xmlで指定すると、aaptが見つからないとコンパイルエラーを起こす。

エラーメッセージは@mipmap/IconLauncherForegroundが見つからないという感じで、@color/IconLauncherBackgroundは見つかってる模様。

原因

エクスプローラーでXamarin.Androidのビルドで生成されるファイルを覗きに行くと、どうもコンパイル時にファイル名がlowercaseにされている模様

ここまでわかれば対策は簡単でさきほどのxmlコードを以下のように直せばコンパイルは通るようになる

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@color/IconLauncherBackground"/>
    <foreground android:drawable="@mipmap/iconlauncherforeground"/>
</adaptive-icon>

Android リソースの基本 - Xamarin

XML ファイルの形式のユーザー インターフェイス レイアウトや、既定のリソースを構成する 5 つのファイルなど、Android リソースの基本について説明します。

docs.microsoft.com

Android リソースの基本 - Xamarin
Go to Android リソースの基本 - Xamarin

または Android には、リソース アイテムのファイル名が小文字のみがサポートされます、Xamarin.Android では少し寛容; に注意してください。これは、大文字と小文字の両方のファイル名をサポートします。

このことはXamarin.Androidのリファレンスにも書いてることだったので自分が見落としていたということなのだろう……

諸悪の原因はリソースファイル名をlowercaseしか受け付けないaaptのほうにあると思うんだけど

じゃあどうすればいいのか

C#er的にはコード上にlower_snake_caseが出没するということは許されないので、リソース名/リソースファイル名はUpperCamelCase一択

この問題はリソース名の場合は起きない(というかリソース名の場合は大文字が許されてる)のでリソースファイル名の場合のみ気をつければよい。

具体的には以下の場合など

  • drawableやmipmapリソースをlayoutリソースやAndroidマニフェストで指定するとき
  • layoutリソースをlayoutリソースで指定するとき
    • これはCustomViewとか作ってる場合に遭遇する可能性がある

つまり、リソースファイル名がリソースIdになるときに、aapt以降(つまりXamarin.Androidの領域外)でリソースIdを指定する場合には気を付ける(lowercase指定)すればよい