Ultimate guide of Dependency Injection (Hilt) in Real world Android Project (Part-2)
အရင်တစ်ပိုင်းမှာကျွန်တော်တို့ setup လုပ်ပုံလေးပြောပီးပီးဆိုတော့ deep-dive လေးသွားကြည့်ရအောင်
Components
Dagger ကော Hilt မှာကော နှစ်ခုစလုံးမှာ Android Lifecycle နဲ့သက်ဆိုင်တဲ့ dependencies တွေပါပါတယ်။
Hilt က Dagger နဲ့ မတူတာက Dagger လို directly သွားရေးစရာမလိုပဲ predefined components ကို generate လုပ်နိုင်တာပါ။
Hilt ရဲ့ predefined components တွေက
- SingletonComponent
- ActivityRetainedComponent
- ViewModelComponent
- ActivityComponent
- FragmentComponent
- ViewComponent
- ViewWithFragmentComponent
- ServiceComponent တို့ပဲဖြစ်ပါတယ်။
Component Hierarchy
SingletonComponent
SingletonComponent ဆိုတာ component ထဲမှာပါတဲ့ top-most layer အဖြစ်ဆုံးပါ။ သူက app က live ဖြစ်နေသရွေ့ အလုပ်လုပ်ပါတယ်။ Application exit ဖြစ်မှသာ သူလဲ exit ဖြစ်တာပါ။ ဘယ်မှာသုံးလို့ကောင်းလဲဆိုတော့ Repositories , API services provide လုပ်ပေးတာတွေနဲ့ Shared Preferences/DataStore တွေမှာ အများဆုံးသုံးကြပါတယ်။ Top-most ဖြစ်တဲ့အတွက်နေရာတိုင်းသုံးလို့ရပေမဲ့ performance ထိပါတယ် ၊ နေရာတိုင်းသုံးဖို့ recommend မပေးပါဘူး
@Module
@InstallIn(SingletonComponent::class)
ActivityRetainedComponent
ActivityRetainedComponent ကတော့ SingletonComponent ရဲ့အောက်ကဒုတိယ top-most အဖြစ်ဆုံးပါ။ သူကတော့ App live ဖြစ်နေသရွေ့တော့ မrun ပါဘူး။ Activity recreated နဲ့ destroyed ဖြစ်တဲ့ configuration change တဲ့ Activity Lifetime မှာ exit ဖြစ်ပါတယ်။
@Module
@InstallIn(ActivityRetainedComponent::class)
ViewModelComponent
Viewmodel Component ကတော့ Viewmodel lifecycle အတိုင်း survive ဖြစ်တာပါပဲ။ ViewModel lifetime က Application Lifetime လောက်မကြာပေမဲ့ Activity နဲ့ Fragment Lifetime ထက်တော့ပိုကြာပါတယ်။
ViewModelComponent တွေက SavedStateHandlerနဲ့သက်ဆိုင်တဲ့ Viewmodel တွေမှာ default binding အနေနဲ့ပါ၀င်ပါတယ်။
@Module
@InstallIn(ViewModelComponent::class)
object Example{
@Provides
@ViewModelScoped
// function provide
}
ActivityComponent
ActivityComponent ကတော့ Activity Lifecycle အတိုင်း survive ဖြစ်တာပါ။ Activity destroyed ဖြစ်သွားရင် သူလဲ destroyed ဖြစ်သွားမှာပါပဲ။
@AndroidEntryPoint
class MainActivity : AppCompatActivity(){
@Inject
lateinit var database: AppDatabase
}@ActivityScoped
class AppDatabase: RoomDatabase{}
FragmentComponent
FragmentComponent ကတော့ Fragment Lifecycle အတိုင်း survive ဖြစ်မှာပါ။ ActivityComponent က parent ဖြစ်တဲ့အတွက် ActivityComponent ရဲ့ binding အတွေအကုန် default ပါလာမှာပါ။
@FragmentScoped
class AppDatabase: RoomDatabase{}
ViewComponent
ViewComponent ကတော့ view attach ထားတဲ့ Activity Lifecycle အတိုင်း survive ဖြစ်မှာပါ။
သူကလဲ ActivityComponent, SingletonComponent နဲ့ ActivityRetainedComponent ထဲက binding အတွေအကုန် default ရပါတယ်။သူ့ကိုသုံးတာတော့ရှားပါတယ်။သိထားသင့်တယ်ထင်လို့ပါ
ViewWithFragmentComponent
ViewWithFragmentComponent ကတော့ Fragmentမှာ Viewရှိမယ်၊ Fragment က အဲ့ view ကို create လုပ်ဖို့ onCreateView နဲ့ destroyed လုပ်မဲ့ onDestroyView လုပ်တဲ့ duration မှာ exit ဖြစ်မှာပါ။ သူလဲ အသုံးမများတဲ့အပြင် ကျွန်တော်လဲမသုံးဘူးတော့ example မထည့်ပေးတော့ပါဘူး။
သေချာတာကတော့ FragmentComponent, ActivityComponent , SingletonComponent နဲ့ ActivityRetainedComponet ရဲ့ binding တွေအကုန် default ရမှာပါ။
ServiceComponent
ServiceComponent ကတော့ Service Lifecycle အတိုင်း survive ဖြစ်ပါတယ်။
သူရဲ့ parent component က SingletonComponent ဖြစ်တဲ့အတွက် SingletonComponent က binding တွေကို default binding အနေနဲ့ရမှာပါ
Binding to Components
Components တွေကို bind ဖို့အတွက်
@InstallIn
နဲ့သုံးပါတယ်။ InstallIn က Module နဲ့ EntryPoint classes တွေမှာပဲသုံးလို့ရတာပါ။
Module
@InstallIn(SingletonComponent::class)
@Module
object NetworkModule {
...
}
EntryPoint
class MyContentProvider : ContentProvider() {
@EntryPoint
@InstallIn(SingletonComponent::class)
interface MyContentProviderEntryPoint {
fun analyticsHelper(): AnalyticsHelper
}
...
}
Component Internals
Component တွေကို bind ဖို့အတွက်
@DefineComponent
// annotation for define components
ကိုအသုံးပြုနိုင်ပါတယ်
Example
import dagger.hilt.DefineComponent
import javax.inject.Singleton
@Singleton
@DefineComponent
interface SingletonComponent
and here
@FragmentScoped
@DefineComponent(parent = ActivityComponent::class)
interface FragmentComponent
Custom components တွေ ကို defined ဖို့အတွက် limitation တော့ရှိပါတယ်
- Components တွေက SingletonComponent တွေရဲ့ direct or indirect child ဖြစ်ရပါမယ်။
- Custom Components တွေကို ActivityComponent နဲ့ FragmentComponent ကြားထဲမှာထည့်လို့မရပါဘူး
နောက်အပိုင်းကျရင်တော့ scoping အကြောင်းဆက်ရှင်းပြသွားပါမယ်….
See you Next Story 😉😉
References
https://developer.android.com/training/dependency-injection/hilt-android