2020-06-11
by viewModels() | ActivityViewModelsでClassCastException
結論
fragment-ktx 1.1.0-alpha04を使っている場合はアップデートする
経緯
ActivityやFragmentでViewModelインスタンスを取得する際、ViewModelProviders.of
を使って生成していたが、非推奨になっていた為、推奨方法に乗り換えようとした。
直接ViewModelProviderを使って生成する
FragmentのAndroid-KTXがAACViewModelの取得に便利だ
こちらの解説が大変丁寧に記述されており、かつわかりやすい内容だったのでbuild.gradle
にバージョン情報も含めて記載した。
bash: title=app/build.gradle1dependencies { 2 implementation 'androidx.fragment:fragment-ktx:1.1.0-alpha04' 3} 4 5
java: title=SomethingDetailFragment.kt1class SomethingDetailFragment : Fragment() { 2 3 private lateinit var binding: SomethingDetailFragmentBinding 4 5 private val sharedViewModel: SomethingViewModel by activityViewModels() 6 7 override fun onCreateView( 8 inflater: LayoutInflater, container: ViewGroup?, 9 savedInstanceState: Bundle? 10 ): View? { 11 binding = SomethingDetailFragmentBinding.inflate(inflater, container, false) 12 binding.viewmodel = sharedViewModel 13 14 binding.viewmodel!!.sometnig.observe(viewLifecycleOwner, Observer { 15 val adapter = binding.SomethingDetailRv.adapter as SomethingDetailAdapter? 16 adapter?.setItem(it!!) 17 Log.v("SomethingDetail","Observe event!") 18 }) 19 this.binding = binding 20 21 setHasOptionsMenu(true) 22 return binding.root 23 24 } 25
エラーの内容
ただし、バージョンが古い事と利用している何らかのライブラリと合わずエラーが発生してしまった。
java.lang.ClassCastException: com.example.android.app.screen.detail.SomethingDetailFragment cannot be cast to androidx.lifecycle.ViewModelStore
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:53)
at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
at com.example.android.app.screen.detail.SomethingDetailFragment.getSharedViewModel(Unknown Source:2)
at com.example.android.app.screen.detail.SomethingDetailFragment.onCreateView(SomethingDetailFragment.kt:30)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:310)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1185)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2222)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1995)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1951)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
試行錯誤
試行錯誤の末、バージョン情報を確認したところ、だいぶ古いものを使ってしまっていたことが判明した。
更新前
gradle: title=app/build.gradle(before)1dependencies { 2 implementation 'androidx.fragment:fragment-ktx:1.1.0-alpha04' 3} 4
更新後
gradle: title=app/build.gradle(after)1dependencies { 2 implementation 'androidx.fragment:fragment-ktx:1.2.4' 3} 4
反省
提供されている記事自体は大変参考になったし、一次情報と照らし合わせながら実装まで試みたは良いものの、バージョンの確認が甘かったなと反省。
参考
ありがとうございました
/以上
よかったらシェアしてください!