by viewModels() | ActivityViewModelsでClassCastException

結論

fragment-ktx 1.1.0-alpha04を使っている場合はアップデートする

経緯

ActivityやFragmentでViewModelインスタンスを取得する際、ViewModelProviders.ofを使って生成していたが、非推奨になっていた為、推奨方法に乗り換えようとした。

直接ViewModelProviderを使って生成する

FragmentのAndroid-KTXがAACViewModelの取得に便利だ

こちらの解説が大変丁寧に記述されており、かつわかりやすい内容だったのでbuild.gradleにバージョン情報も含めて記載した。

app/build.gradle
dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.1.0-alpha04'
}
SomethingDetailFragment.kt
class SomethingDetailFragment : Fragment() {

    private lateinit var binding: SomethingDetailFragmentBinding

     private val sharedViewModel: SomethingViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = SomethingDetailFragmentBinding.inflate(inflater, container, false)
        binding.viewmodel = sharedViewModel

        binding.viewmodel!!.sometnig.observe(viewLifecycleOwner, Observer {
            val adapter = binding.SomethingDetailRv.adapter as SomethingDetailAdapter?
            adapter?.setItem(it!!)
            Log.v("SomethingDetail","Observe event!")
        })
        this.binding = binding

        setHasOptionsMenu(true)
        return binding.root

    }

エラーの内容

ただし、バージョンが古い事と利用している何らかのライブラリと合わずエラーが発生してしまった。

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)

試行錯誤

試行錯誤の末、バージョン情報を確認したところ、だいぶ古いものを使ってしまっていたことが判明した。

更新前

app/build.gradle(before)
dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.1.0-alpha04'
}

更新後

app/build.gradle(after)
dependencies {
    implementation 'androidx.fragment:fragment-ktx:1.2.4'
}

反省

提供されている記事自体は大変参考になったし、一次情報と照らし合わせながら実装まで試みたは良いものの、バージョンの確認が甘かったなと反省。

参考

ありがとうございました

/以上