滅入るんるん

何か書きます

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

事の発端

f:id:meilcli:20181123142749p:plain

<?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は見つかってる模様。

原因

f:id:meilcli:20181123143229p:plain

エクスプローラーで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 | Microsoft Docs

または 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指定)すればよい