clearという名前のメソッドをもつViewModelのサブクラスをdalvikvm上で見つけられない人へ
年末、android-ktxをプロジェクトに入れようとして思わぬところで躓いたのでメモしておく。現象としては、Android 5.0以上が動いているエミュレータでは問題ないのに、4.4のエミュレータではアプリが起動するときにクラッシュしてしまうというもので、LogCatには特定のViewModel
のサブクラスをロードするときにClassNotFoundException
が発生した旨のスタックトレースが出ていた。
以下、手短に:
- 前提知識
- dalvikvmではpackage-privateなメソッドがパッケージ外からoverrideされてしまう(https://issuetracker.google.com/issues/36980050)。
- Javaではpackage-privateなメソッドと、そのサブクラスのメソッドとが同じ名前であった場合、それぞれ別のメソッドという扱いになる。
- ARTではこの不具合は修正されている様子。
- viewmodel 2.1.0-alpha01でpackage-privateな
final void clear()
というメソッドがViewModel
に追加された(https://android.googlesource.com/platform/frameworks/support/+/cc482665dae9b47b09bc818f39fbb01c36cf0d75%5E%21/#F5)- fragment-ktx 1.1.0-alpha03の依存関係で入ってきた模様。
- dalvikvmではpackage-privateなメソッドがパッケージ外からoverrideされてしまう(https://issuetracker.google.com/issues/36980050)。
- クラッシュする理屈:
clear()
という名前のメソッドを持つViewModel
のサブクラスは、dalvikvm上では親クラスのViewModel.clear()
をoverrideすることになるが、ViewModel.clear()
はfinal
なのでoverrideできない*1。これによってViewModel
のサブクラスは仮想マシンに読み込まれず、クラスが見つからない系のランタイムエラーが発生する。 - 対応
- サブクラスのclearメソッドの名前を変えました…
- こういうのはAOSPに報告すべき?