Apakah mungkin meneruskan ViewModel ke Fragment di konstruktor?

Saya menggunakan Koin untuk DI tetapi saya mencoba menghilangkan ketergantungan pada kerangka DI jadi pertanyaan saya adalah tentang Komponen Arsitektur Android secara umum.

Dimungkinkan untuk menyediakan instance ViewModel dengan delegasi properti dalam fragmen tetapi hal ini menyebabkan penggabungan antara fragmen dan kerangka DI. Jadi saya menemukan solusi: meneruskan ViewModel ke Fragment di konstruktor. Implementasi saat ini dengan Koin terlihat seperti ini:

val di = module {
    fragment {
        MyFragment(
            get<MyViewModel>(),
        )
    }
    viewModel {
        MyViewModel(
            get<MyDependency>(),
        )
    }
    //...
}

Dan itu berhasil. Tapi ada batasannya. Karena ViewModel dibuat sebelum Fragmen, ia tidak mengikuti siklus hidup Fragmen dan onCleared() tidak dipanggil ketika Fragmen dihancurkan.

Jadi saya bertanya-tanya bagaimana cara membuatnya berfungsi kembali?


person oleg.semen    schedule 13.03.2021    source sumber


Jawaban (2)


Sebenarnya isu tersebut sama sekali tidak berhubungan dengan Koin. Untuk membuat ViewModel dengan benar (terikat dengan siklus hidup), Anda memerlukan referensi ke ViewModelProvider yang dapat dibuat menggunakan Fragmen atau Aktivitas.

Jadi, Anda harus memiliki referensi ke Fragment atau Activity terlebih dahulu. Hal ini membuat tidak mungkin meneruskan ViewModel sebagai argumen konstruktor ke fragmen.

Untuk menghilangkan ketergantungan pada Koin, Anda dapat menggabungkan fungsi ekstensi Koin viewModel() dalam fungsi Anda sendiri, sehingga Anda dapat menukar DI, jika diperlukan.

person Aleksei Potapkin    schedule 23.04.2021
comment
Dari apa yang saya lihat ViewModelProvider memiliki referensi ke ViewModelStoreOwner yang merupakan antarmuka. Aktivitas dan fragmen adalah implementasi default dari antarmuka ini tetapi saya yakin modul Koin (atau cakupan atau sesuatu yang lain di Koin) dapat memainkan peran ViewModelStoreOwner. Atau apakah saya melewatkan sesuatu tentang penggabungan ViewModelProvider ke aktivitas dan fragmen? - person oleg.semen; 23.05.2021
comment
Namun Anda memerlukan ViewModelStoreOwner untuk menjadi lifecycleOwner jika Anda ingin mengikat ViewModel ke siklus hidup aktivitas/fragmen. Atau tidak akan ada panggilan onCleared() yang tepat ketika aktivitas berhenti. - person Aleksei Potapkin; 26.05.2021

Pada tingkat dasar, fragmen adalah objek sehingga Anda dapat meneruskan parameter ke konstruktor fragmen. Namun, ini bukan praktik yang baik dan Anda harus selalu menghindarinya karena Android adalah sistem berbasis peristiwa sehingga Anda harus berperilaku sesuai. Begitu banyak masalah berbeda yang dapat muncul karena praktik buruk ini, tetapi mari kita fokuskan masalah Anda. Secara internal, metode onCleared() dari model tampilan dipanggil oleh viewModelStoreOwner yang diimplementasikan oleh aktivitas dan fragmen. Oleh karena itu, suatu aktivitas atau fragmen harus menyadari model tampilan ini. Cara paling sederhana untuk memberikan kesadaran tersebut adalah dengan menggunakan metode ekstensi viewModels. ( https://developer.android.com/kotlin/ktx#fragment ) . Ini secara langsung menghubungkan model tampilan Anda dengan fragmen atau aktivitas Anda secara internal. Namun, dengan solusi ini kita harus mempertimbangkan masalah lain yaitu Bagaimana kita memasukkan objek lain (repositori, use case, dll.) ke dalam model tampilan kita. Untuk melakukan ini kita perlu mengimplementasikan pabrik model tampilan kustom. Saya tidak yakin bagian ini diperlukan untuk Koin sehingga Anda dapat melihat https://insert-koin.io/docs/reference/koin-android/viewmodel/ .

person M.ekici    schedule 13.03.2021
comment
Jika Anda membutuhkan penjelasan lebih teknis saya bisa menjawabnya. - person M.ekici; 14.03.2021