【Androidで実行時エラー(クラッシュ)対処】Binary XML file line #00: Error inflating class ImageView

<h3>概要</h3>
Androidスマートフォン向けアプリケーション開発にて、コンパイルは通るが、起動中に特定の画面を表示しようとした際、エラーとなりクラッシュする事象が起きた。

このとき、エミュレータ（AVD / Android Virtual Device）で実行しても問題なく動作したが、実機で実行したときだけ事象が確認できた。

<h3>検証環境</h3>

- Android Studio 3.1.4
- macOS Sierra バージョン10.12.6

<h3>エラー出力</h3>

```
09-22 18:24:58.768 4694-4694/com.example D/AndroidRuntime: Shutting down VM

    --------- beginning of crash
09-22 18:24:58.768 4694-4694/com.example E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example, PID: 4694
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.ui.activity.MainActivity}: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class ImageView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class ImageView
        at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
        at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.ui.activity.MainActivity.onCreate(MainActivity.kt:20)
```

Android Studioにて、Logcatを表示しながら事象を再現すると、クラッシュするタイミングで上記のエラーが出力された。

<h3>調査</h3>

リソースIDが見つからないらしい。スタックトレースを見ると `MainActivity.kt:20` とあるが、この行は以下のような実装となっていた。

```
class MainActivity : AppCompatActivity() {

    // 省略...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) // line: 20

        // 省略...

    }

    // 省略...

}
```

該当の行： `setContentView(R.layout.activity_main) // line: 20` では、 `view` を `set` している。

この `activity_main` を見てみると、以下のような実装になっていた。

```
<?xml version="1.0" encoding="utf-8"?>

<!-- 省略... -->

    <ImageView
        app:srcCompat="@drawable/ic_app" />

<!-- 省略... -->
```

`ImageView` で `drawable` にある `ic_app` という名前のリソースを使用している。
Logcatの出力にも `Binary XML file line #00: Error inflating class ImageView` とあったので、この `activity_main` の `drawable/ic_app` がクラッシュの原因らしい。

この画像ファイルの格納ディレクトリが `com.example/app/src/main/res/drawable-v24/ic_app.png` となっていた。

<h3>原因</h3>

このディレクトリはAndroid APIバージョンが24以降でのみ認識される。
事象が確認できた端末のAPIバージョンは23、正常に動作した端末のAPIバージョンは26だった。

該当の画像の格納ディレクトリを変更したら、事象が解消されるのではないかと見当がついた。

<h3>対応手順</h3>

`com.example/app/src/main/res/drawable-v24/ic_app.png` にある画像ファイルを

`com.example/app/src/main/res/drawable/ic_app.png` に移動する。

※いずれも、 `drawable/ic_app` でアクセスできるので、リソースを使用する側の `.kt` 、 `.java` 、 `.xml` などは変更しなくてよい

これでクラッシュすることなくアプリケーションが動作し、件の画像も読み込める。

<h3>備考</h3>

- 上の例では `drawable/ic_app.png` としていたが、Androidの開発において、アイコン画像は `.svg` のほうが好ましい。（複数の画像を用意することなく色やサイズを変更できるため）
- 上の例では、APIバージョン23（Android 6.0）まで対応しているが、実際はどのAPIバージョンまでサポートするか事前にクライアント（あるいはビジネスサイド）と取り決めておき、サポート対象のバージョンによっては上記のような当記事で紹介したような対応は不要となる。