概要
Androidスマートフォン向けアプリケーション開発にて、コンパイルは通るが、起動中に特定の画面を表示しようとした際、エラーとなりクラッシュする事象が起きた。このとき、エミュレータ(AVD / Android Virtual Device)で実行しても問題なく動作したが、実機で実行したときだけ事象が確認できた。
検証環境
- Android Studio 3.1.4
- macOS Sierra バージョン10.12.6
エラー出力
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を表示しながら事象を再現すると、クラッシュするタイミングで上記のエラーが出力された。
調査
リソース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
となっていた。
原因
このディレクトリはAndroid APIバージョンが24以降でのみ認識される。
事象が確認できた端末のAPIバージョンは23、正常に動作した端末のAPIバージョンは26だった。
該当の画像の格納ディレクトリを変更したら、事象が解消されるのではないかと見当がついた。
対応手順
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
などは変更しなくてよい
これでクラッシュすることなくアプリケーションが動作し、件の画像も読み込める。
備考
- 上の例では
drawable/ic_app.png
としていたが、Androidの開発において、アイコン画像は.svg
のほうが好ましい。(複数の画像を用意することなく色やサイズを変更できるため) - 上の例では、APIバージョン23(Android 6.0)まで対応しているが、実際はどのAPIバージョンまでサポートするか事前にクライアント(あるいはビジネスサイド)と取り決めておき、サポート対象のバージョンによっては上記のような当記事で紹介したような対応は不要となる。