Contoh aplikasi android modular yang menggunakan komponen Navigasi dan Koin (DI)

Pengembang, halo!





Pada artikel kali ini, saya ingin membagikan contoh aplikasi android modular menggunakan NavComponent (JetPack) dan Koin (DI).





Kami memiliki banyak proyek Android berbeda di perusahaan kami yang harus menggunakan fitur satu sama lain - ini adalah sejenis ekosistem. Untuk mencapai ini, kami perlu mengembangkan fitur-fitur ini se-independen dan sefleksibel mungkin.





Persyaratan fitur dapat dirumuskan sebagai berikut:





  1. Sebuah fitur harus dapat menggantikan logika dan UI secara independen satu sama lain.





  2. Untuk memanggil fitur, itu harus cukup untuk mengetahui antarmuka (label) dan parameter input / output yang diperlukan.





  3. Fitur itu sendiri harus menyembunyikan implementasinya dari fitur lain.





  4. Dukungan untuk fitur on-off out of the box.





Bagi saya, fitur adalah sistem gabungan dari komponen yang menjalankan beberapa fungsi dalam aplikasi. Misalnya, otorisasi, pembelian. Sebuah fitur berisi grafik UI-nya sendiri (rangkaian fragmen), yang harus disimpan di navigasi backStack, dan setelah keluar dari fitur, kembalikan pengguna ke titik panggilan fitur.





Skema kondisional aplikasi yang terdiri dari dua fitur:





Diagram menunjukkan aplikasi yang memiliki MainFragment (M) dan dua fitur (A dan B). Dari M kita bisa masuk ke fitur A dan B. Dan dari fitur B kita bisa ke fitur A. Selain itu, setelah fitur A selesai, kita harus kembali ke point of call: jika kita mendapat fitur A dari M, maka kita kembali ke M, dan jika dipanggil fitur A dari B, lalu ke B. Dalam kasus ini, tumpukan navigasi harus dipertahankan. A1, A2, B1, B2 - fragmen fitur.





: API, BL, UI.





.  A -> B - .





  • API , . Lint : API .





  • BL - . API . internal - , DI , . Lint : BL   APP .





  • UI . internal - , DI , NavGraph, nested graph. Lint : UI APP .





:









  • (app)





  • app DI





startKoin {
            modules(
                listOf(
                    AppKoinModule.create(),                 
                    FeatureAImplKoinModule.create(),
                    FeatureAUiKoinModule.create(),
                    FeatureBImplKoinModule.create(),
                    FeatureBUiKoinModule.create()
                )
            )
        }
      
      



, , app DI, , . C UI - , root app .





  • root (app). , , .





  • :





 appNavigator.navigateTo(FeatureADestination::class.java)
      
      



( )





interface FeatureADestination : ModuleNavInfo
      
      



ModuleNavInfo , . FeatureADestination UI .





interface ModuleNavInfo {
    fun getNavigationStartPointResId(): Int

    fun isFeatureAvailable(): Boolean
}
      
      



navigator, . , DI ModuleNavInfo:





class KoinAppNavigator : AppNavigator {

    private val navigationDestinationInternal = MutableLiveEvent<EventArgs<ModuleNavInfo>>()
    override val navigationDestination =
        navigationDestinationInternal as LiveData<EventArgs<ModuleNavInfo>>

    private val navigationIntDestinationInternal = MutableLiveEvent<EventArgs<Int>>()
    override val navigationResDestination: LiveData<EventArgs<Int>>
        get() = navigationIntDestinationInternal

    override fun <T : ModuleNavInfo> navigateTo(
        moduleNavInfo: Class<T>
    ) {
        val destination = KoinJavaComponent.get(moduleNavInfo) as ModuleNavInfo
        navigationDestinationInternal.postValue(EventArgs(destination))
    }

    override fun navigateTo(destination: Int) {
        navigationIntDestinationInternal.postValue(EventArgs(destination))
    }

    override fun <T : ModuleNavInfo> resolveModule(moduleNavInfo: Class<T>): ModuleNavInfo? {
        return try {
            KoinJavaComponent.get(moduleNavInfo)
        } catch (e: Exception) {
            null
        }
    }

    override fun <T : ModuleNavInfo> isCanNavigateTo(moduleNavInfo: Class<T>): Boolean {
        return resolveModule(moduleNavInfo) != null
    }
}

      
      



ModuleNavInfo dan AppNavigator dapat diperpanjang, di sini saya menunjukkan contoh paling sederhana. Misalnya, Anda pasti perlu meneruskan parameter dan mengembalikan hasilnya. Ini juga dapat dilakukan melalui ModuleNavInfo. Misalnya, untuk mengembalikan hasil fitur, Anda dapat menambahkan StateFlow dan berlangganan ke sana. Semuanya ternyata ringkas dan di satu tempat. Anda juga dapat mengonfigurasi interaksi menggunakan layanan internal yang dapat disembunyikan dari dunia luar dalam modul BL.





Kode contoh tersedia di github .





Terima kasih atas perhatiannya!








All Articles