MapView と ViewPager2 の組み合わせでハマる
新しめの端末では問題ないのですが API25(Android 7) あたりから問題がありました。
発生するエラー
MapView と ViewPager2 を一つの画面に配置して、画面の状態を復元するような操作をすると、こんなログを出してクラッシュします。java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class androidx.recyclerview.widget.RecyclerView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x1. Make sure other views do not use the same id.内容としては、違う View なのに同じ View ID (0x1) が割り当てられてるから復元できないよ、という感じです。
原因
イシューが登録されていました。 MapView や ViewPager2 の中に明示的に ID が指定されていない View があり、実行時に ID が割り当てられるのですが、それが並行して動作することで同じ ID を割り当ててしまうようです。 なので、回避策として ID の採番をこちら側で進めてしまうといいらしいです。 詳細は、上記リンク先を参照ください。具体的な回避コード(私の場合)
onCreateView() の中で、View を inflate する前に ID の採番を進めました。override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { for (i in 0 until 10) ViewCompat.generateViewId() binding = FragmentMainBinding.inflate(inflater, container, false) binding.mapView.onCreate(savedInstanceState) binding.mapView.getMapAsync(this) return binding.root }ちなみに、今回調査を進めるにあたり、初めて Layout Inspector を使いました。 Android Studio の「Tools」→「Layout Inspector」で呼び出せるやつです。 Layout Inspector のツールバーで「Expand All」を実行すると、ビュー階層の中で同じ ID が割り当てられている View がすぐにわかりました。