Ultimate guide of Dependency Injection (Hilt) in Real world Android Project (Part-1)
အစောပိုင်းမှာ Clean Architecture က SOLID PATTERN အကြောင်းရေးဖူးတာရှိပါတယ်။ မဖတ်ရသေးရင်အောက်မှာ Link ပေးထားပါတယ်။
Android Clean Architecture ထဲက မရှိမဖြစ်အရေးပါလှတဲ့ Dependency Injection အတွက် hilt ကိုဘယ်လိုsetup လုပ်ရမလဲဆိုတာပြောပြပေးမှာပါ။
အခုလောလောဆယ် Dagger ဆိုတာဘယ်လဲဘာလဲ….
What is Dagger?
Dagger ဆိုတာက Android က ထုတ်ထားတဲ့ DI framework တစ်ခုဖြစ်ပါတယ်။ အရင်တုန်းက Injection ထိုးရင် custom ထိုးရပါတယ်။ Dagger ကတော့ အစောပိုင်းarticle မှာရေးပီးသားဖြစ်လို့များများစားစား မရှင်းပြတော့ပါဘူး။ Dagger ကနေ Hilt ကို Google က migrate လုပ်လိုက်ရတာက
1. Dagger က Learning curve မြင့်လို့
Team တစ်ခုမှာ Framework တစ်ခုကိုသုံးပီဆို တစ်ယောက်ထဲနားလည်နေလို့မရပါဘူး။ အကုန်လုံးကို နားလည်လွယ်တဲ့ framework တစ်ခုလဲသုံးဖို့လိုပါတယ်။ ဘယ်ဟာမဆို easy to use ဖြစ်ရင်အကောင်းဆုံးမို့လား
2. Boilerplate များတယ်
Injection တစ်ခုရဖို့ကို မျိုးစုံ scope တွေ module တွေအများကြီးသုံးရပါတယ်၊ Dagger ကို project ထဲမှာထည့်ဖူးတဲ့လူတွေဆိုသိမှာပါ။ ခက်ခက်ခဲခဲကိုထည့်ရတာ စာတစ်တန်ပေတစ်တန်နဲ့ ပီးတော့ error တက်ရင် ဘယ်နားကတက်နေလဲမသိတဲ့ပြသနာကပါပါသေးတယ်။
အဲ့ဒါတွေကြောင့် နောက်ပိုင်းမှာ Google က Hilt ကိုပြောင်းလိုက်တာပါ။
How to setup Hilt Dagger?
- Add plugin in Root build.gradle
buildscript {
...
dependencies {
...
classpath("com.google.dagger:hilt-android-gradle-plugin:${latest_version)")
}
}
2. Add Kapt extension plugin and dependencies
plugins {
kotlin("kapt")
id("dagger.hilt.android.plugin")
}
android {
...
}
dependencies {
implementation("com.google.dagger:hilt-android:${latest_version)")
kapt("com.google.dagger:hilt-android- compiler:${latest_version)")
}
// Allow references to generated code
kapt {
correctErrorTypes = true
}
3. Hilt က Java 8 features ကိုသုံးပါတယ်။ ဒါလေးတော့မဖြစ်မနေထည့်ပေးရမှာပါ
android {
...
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
Hilt Core APIs
- Components
- Hilt Application
- Android Entry Points
- Custom Components
ဆိုပီး ၄မျိုးရှိပါတယ်
deep dive လေ့လာချင်ရင် ဒီထဲမှာလေ့လာနိုင်ပါတယ်
အသေးစိတ်ကို နောက်ထပ် story တွေမှာထပ်ရှင်းပြပါမယ်
How to structure with Hilt?
Phase 1
ပထမဆုံး hilt ကိုထည့်ဖို့အတွက် Application ကို ဒီလိုပြောင်းလဲပေးရပါတယ်
@HiltAndroidApp
class App : Application()
Phase 2: နောက်ထပ် Module create လုပ်ဖို့လိုပါတယ်
@Module
@InstallIn(SingletonComponent::class)
object ApplicationModule{
//to provide or inject function
}
နောက်ထပ် api ကို provide လုပ်ပုံပြောပြပါမယ်
သိထားရမှာက Provide နဲ့ Binds နှစ်ခုရှိတယ်ဆိုတာပါပဲ။ Binds အကြောင်းနဲ့ Detail အကြောင်းကို နောက်ထပ် article နဲ့သပ်သပ်ရှင်းပြပါမယ်
အခုတော့ Provides နဲ့ရေးကြည့်ရအောင်
အဲ့လိုကြေညာရပါတယ်။ အလွယ်မှတ်ရရင်တော့ multi modularization လုပ်ရင်လဲ SingletonComponent ပဲသုံးကြတာများပါတယ် WorkManager လိုဟာမျိုးရေးရင်တော့ Custom Components သုံးလို့ရပါတယ်။
ပြန်ပီးအသုံးပြုတဲ့ပုံစံကတော့
class ExampleRemoteImpl @Inject constructor(
private val api: ApiService,
private val mapper: ExampleMapper
) : ExampleRemote {}
ExampleService.class
interface ApiService{
@GET
fun fetchNetworkCall () : Response<Something()>
}
အဲ့ကောင်ကိုခေါ်တာပါ retrofit နဲ့ချိတ်ထားတာပေါ့။
Phase 3 : AndroidEntryPoint ကြေညာခြင်း
Fragment သို့မဟုတ် Activity တွေမှာ AndroidEntryPoint ဆိုပီးကြေညာရပါတယ်
@AndroidEntryPoint
class ExampleFragment : Fragment(){}
AndroidEntryPoint ကို အသုံးပြုတဲ့နေရာတွေကတော့
- Activity
- Fragment
- View
- Service
- BroadcastReceiver တို့ပဲဖြစ်ပါတယ်
Phase 4 : ViewModel ကြေညာတာ
Viewmodel တွေတိုင်းမှာ HiltViewModel ဆိုပီးကြေညာရပါတယ်
@HiltViewModel
class ExampleViewModel @Inject constructor()
ပြန်ခေါ်သုံးလို့ရမယ့်ပုံစံကတော့
@AndroidEntryPoint
class ExampleFragment : Fragment(){
....
private val viewModel: AttractionListViewModel by viewModels()
}
အလွယ်တကူပြန်ခေါ်သုံးလို့ရမှာဖြစ်ပါတယ်။ အပေါ်က HiltViewModel ထဲက Inject constructor ခံထားတာက AppModule ထဲက Repository inject လုပ်ထားတဲ့ ဟာတွေထည့်ရတာပါ
နောက်အပိုင်းကျရင် migration နဲ့ detail အကြောင်းတွေကို ဆက်ပီးရှင်းပြပေးပါမယ် …