Dagger — bu Java va Kotlin uchun bog'liqliklarni kiritish freymvorki bo'lib, annotatsiyalarni qayta ishlash orqali kompilyatsiya bosqichida DI kodini yaratadi. Hilt — bu Android uchun Dagger ustidagi qo'shimcha bo'lib, komponentlar va hayotiy tsiklni sozlashni soddalashtiradi. Google, 2025 ma'lumotlariga ko'ra, Hilt Google Play Top-100 dagi Android ilovalarining 70% dan ortig'ida qo'llaniladi, Activity, Fragment, ViewModel va Service-ni oldindan belgilangan komponentlar orqali qo'llab-quvvatlaydi. Ikkala freymvork ham bog'liqlik grafigini kompilyatsiya vaqtida tekshirishni ta'minlab, ishga tushirish vaqtidagi kiritish xatolarini bartaraf qiladi.
Asosiy ma'lumotlar
Dagger — bu kompilyatsiya bosqichida kod yaratuvchi bog'liqliklarni kiritish freymvorki (compile-time DI). Square da ishlab chiqilgan va keyinchalik Google ga berilgan Dagger, bog'liqlik grafigini tahlil qilish va fabrika sinflarini yaratish uchun Java APT annotatsiya protsessoridan foydalanadi. Runtime-DI (Guice, Koin) dan farqli o'laroq, Dagger refleksiyadan foydalanmaydi — barcha kod kompilyatsiya vaqtida yaratiladi, bu esa ish vaqtida maksimal ishlashni va qurish bosqichida xatolarni aniqlashni ta'minlaydi.
Hilt — bu Google-dan Dagger asosida qurilgan va Android uchun optimallashtirilgan kutubxonadir. Hilt Android komponentlarining hayotiy tsikliga mos keladigan oldindan belgilangan komponentlarni taqdim etadi: Application uchun @SingletonComponent, Activity uchun @ActivityComponent, Fragment uchun @FragmentComponent, ViewModel uchun @ViewModelComponent. Bu toza Dagger da talab qilinadigan Component va Module ni muntazam sozlashni bartaraf qiladi. Hilt, shuningdek, @AndroidEntryPoint orqali har bir Android komponenti uchun avtomatik ravishda bog'liqlik grafigini yaratadi.
Google I/O 2024 ma'lumotlariga ko'ra, Hilt Kotlin da yozilgan Android ilovalari uchun tavsiya etilgan DI yechimidir. Jetpack kutubxonalari (Navigation, Room, WorkManager) @HiltViewModel va @HiltWorker orqali Hilt bilan o'rnatilgan integratsiyaga ega. Android dan foydalanmaydigan loyihalarda (toza Java/Kotlin kutubxonalari, server ilovalari) Hilt qo'shimchasisiz toza Dagger qo'llaniladi.
DI freymvorkisiz dasturchi obyektlarni qo'lda konstruktorlar yoki fabrikalar orqali yaratadi, bog'liqliklarni zanjir bo'ylab uzatadi. Har bir yangi talab — zanjirdagi barcha konstruktorlarning imzosini o'zgartirish. Dagger bu jarayonni avtomatlashtiradi: qaysi tur talab qilinishini e'lon qilish kifoya (@Inject constructor), va Dagger barcha ichma-ich turlarni hal qilib, bog'liqlik grafigini yaratadi. Bog'liqliklar o'zgarganda Dagger yaratilgan kodni avtomatik yangilaydi — zanjirda xato qilish mumkin emas.
Bog'liqliklarni kiritish (Dependency Injection) — bu obyekt o'z bog'liqliklarini tashqaridan oladigan, o'zi yaratmaydigan namunadir. DI boshqaruvni teskari o'zgartirish (IoC) tamoyilini amalga oshiradi: sinf o'z bog'liqliklarini yaratish uchun javobgar emas, balki ularni konstruktor, metod yoki maydon orqali e'lon qiladi. Konstruktor orqali kiritish (constructor injection) eng maqbul usul hisoblanadi, chunki u obyektning haqiqiy holatda yaratilishini kafolatlaydi.
| Kiritish turi | Dagger sintaksisi | Qachon ishlatiladi |
|---|---|---|
| Constructor injection | @Inject constructor | Asosiy usul — barcha o'z sinflari uchun |
| Field injection | @Inject lateinit var | Faqat Android komponentlari uchun (Activity, Fragment) |
| Method injection | @Inject fun bind() | Post-construct ishga tushirish uchun |
DI ning asosiy afzalliklari sinovdan o'tkazish qobiliyati (bog'liqliklar mock-obyektlar bilan almashtirilishi mumkin), zaif bog'lanish (sinflar implementatsiyalarga emas, interfeyslarga bog'liq) va scopes orqali obyektlarning hayotiy tsiklini ochiq boshqarishni o'z ichiga oladi. Dagger avtomatik ravishda obyektning o'z scope-i doirasida bir marta yaratilishini va scope-dan chiqishda yo'q qilinishini kafolatlaydi.
Component — Dagger bog'liqlik grafigining markaziy elementidir. Bu Module va kiritish maqsadlari o'rtasidagi ko'prikni tavsiflovchi @Component bilan annotatsiya qilingan interfeysdir. Dagger kompilyatsiya bosqichida Component implementatsiyasini (masalan, DaggerAppComponent) yaratadi. Component, abstrakt metodlar orqali kerakli turlarni qaytarish yoki field injection uchun obyektni qabul qiluvchi inject metodlari orqali qaysi turlar kiritish uchun mavjudligini aniqlaydi.
// Modul: Dagger o'zi yarata olmaydigan bog'liqliklarni ta'minlaydi
@Module
class NetworkModule {
@Provides
@Singleton
fun provideOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.build()
}
@Provides
@Singleton
fun provideApiService(client: OkHttpClient): ApiService {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
// Komponent: Module va kiritish maqsadlarini bog'laydi
@Component(modules = [NetworkModule::class])
interface AppComponent {
fun inject(activity: MainActivity)
fun getApiService(): ApiService
}
@Module — bu bog'liqlik namunalarini qaytaruvchi @Provides metodlarini o'z ichiga olgan sinfdir. Module Dagger avtomatik yarata olmaydigan turlar uchun ishlatiladi: uchinchi tomon kutubxonalari (OkHttp, Retrofit), konstruktor parametrlari bo'lgan obyektlar, implementatsiya tanlovi bo'lgan interfeyslar. @Binds — metod interfeysni qaytarganda va yagona implementatsiyani qabul qilganda @Provides uchun alternativadir: Dagger metodni chaqirmasdan to'g'ridan-to'g'ri cast yaratadi.
@Scope obyektning bog'liqlik grafigidagi hayot muddatini belgilaydi. @Singleton — obyekt butun ilova uchun bir marta yaratiladi. @ActivityScoped — obyekt Activity yashaguncha yashaydi. @FragmentScoped — Fragment yashaguncha yashaydi. Scopesiz Dagger har bir kiritishda yangi namuna yaratadi. @Reusable — singleton bo'lishi shart bo'lmagan, ammo yaratilishi qimmat bo'lgan obyektlar uchun scope — Dagger namunani keshlashi mumkin, ammo buni kafolatlamaydi.
Hilt oldindan belgilangan komponentlar va asosiy grafikning avtomatik yaratilishi tufayli Android uchun Dagger sozlamalarini soddalashtiradi. Application sinfidagi @HiltAndroidApp annotatsiyasi Hilt komponentini yaratishni ishga tushiradi. Ushbu annotatsiyasiz Hilt ishlamaydi — Hilt dan foydalanadigan har bir Android ilovasi uchun majburiydir. @HiltAndroidApp barcha boshqa ilova komponentlari meros oladigan ota-ona SingletonComponent ni yaratadi.
@HiltAndroidApp
class MyApplication : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var apiService: ApiService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// apiService onCreate chaqirilishidan oldin allaqachon kiritilgan
}
}
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Provides
@Singleton
fun provideDatabase(@ApplicationContext ctx: Context): AppDatabase {
return Room.databaseBuilder(ctx, AppDatabase::class.java, "app.db").build()
}
}
@AndroidEntryPoint — Activity, Fragment, Service, BroadcastReceiver va View uchun annotatsiyadir. Har bir tur uchun Hilt komponentini yaratadi: Activity dagi @AndroidEntryPoint SingletonComponent dan meros oladigan ActivityComponent ni yaratadi. Farzand komponent avtomatik ravishda ota-onaning barcha bog'liqliklarini oladi. @Inject lateinit var bilan field injection faqat @AndroidEntryPoint bilan annotatsiya qilingan sinflarda mavjud — oddiy sinflarda constructor injection ishlatiladi.
@InstallIn modul qaysi Hilt komponentiga o'rnatilishini ko'rsatadi. @InstallIn(SingletonComponent::class) bilan NetworkModule butun ilovada mavjud. @InstallIn(ActivityComponent::class) bilan Module — faqat Activity da. Bu bog'liqlik grafiklarini izolyatsiya qiladi: Activity ga xos modullar Fragment va ViewModel da ko'rinmaydi, ruxsat etilmagan bog'liqliklarning tasodifiy ishlatilishini oldini oladi. @ApplicationContext — ilova kontekstini olish uchun Hilt ning o'rnatilgan kvalifikatori.
Bir xil interfeysning ikki xil implementatsiyasini kiritish talab qilinganda, kvalifikatorlardan foydalaniladi. Hilt matn identifikatorlari uchun @Named ni va @Qualifier bilan shaxsiy annotatsiyalarni qo'llab-quvvatlaydi. Masalan, turli matn konfiguratsiyalari uchun @Named("baseUrl") va @Named("imageBaseUrl"). Shaxsiy kvalifikatorlar @Named dan afzal, chunki kompilyatsiya bosqichida tekshiriladi — noto'g'ri matn nomi ish vaqtigacha aniqlanmaydi.
@HiltViewModel — qo'lda ViewModelProvider.Factory fabrikasini almashtiruvchi annotatsiyadir. @HiltViewModel bilan annotatsiya qilingan va @Inject constructor ga ega sinf barcha bog'liqliklarni avtomatik ravishda Dagger orqali oladi. Hilt Jetpack ViewModelProvider tomonidan ishlatiladigan ViewModelFactory ni yaratadi. Hilt siz dasturchi fabrikani qo'lda yozishi, har bir parametrni Activity yoki fragmentdan uzatishi kerak bo'ladi.
@HiltViewModel
class MainViewModel
@Inject constructor(
private val apiService: ApiService,
private val database: AppDatabase
) : ViewModel() {
private val _users = MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> = _users.asStateFlow()
fun loadUsers() {
viewModelScope.launch {
_users.value = apiService.getUsers()
}
}
}
// Activity da — Hilt avtomatik ViewModel yaratadi
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
}
ViewModelScoped — ViewModel yashaguncha yashaydigan bog'liqliklar uchun Hilt scope i. Agar bir xil turdagi ikkita ViewModel bir xil @ViewModelScoped bog'liqlikni kiritsa, har biri o'z namunasini oladi. Bu @ViewModelScoped ni @ActivityScoped dan farqlaydi, bu erda bitta Activity barcha fragmentlar uchun bitta namuna oladi. ViewModel ga xos bog'liqliklar uchun (masalan, SavedStateHandle) @HiltViewModel @Inject constructor(savedStateHandle: SavedStateHandle) bilan ishlatiladi.
Hilt Hilt Extensions kutubxonasi orqali assisted injection ni qo'llab-quvvatlaydi. Assisted injection bog'liqliklarning bir qismi faqat ish vaqtida ma'lum bo'lganda (masalan, intent dan foydalanuvchi ID si) konstruktorga parametrlarni uzatishga imkon beradi. Assisted injection uchun @AssistedInject @Assisted parametrlari bilan kombinatsiyada ishlatiladi. Hilt standart usulda kiritilishi mumkin bo'lgan AssistedFactory ni yaratadi.
Toza Dagger qo'lda Component yaratishni, scope larni belgilashni va har bir Android komponentida kiritishni sozlashni talab qiladi. Dasturchi AppComponent, ActivityComponent, FragmentComponent yaratadi, ularning munosabatlarini @Subcomponent orqali boshqaradi. Ushbu yondashuv maksimal nazoratni beradi, ammo sezilarli miqdordagi boilerplate kodni talab qiladi. Dagger nostandart DI arxitekturasi talab qilinadigan katta loyihalarda yoki Android bo'lmagan Java/Kotlin loyihalarida ishlatiladi.
Hilt boilerplate ni avtomatlashtiradi: bitta @HiltAndroidApp, har bir komponent uchun bitta @AndroidEntryPoint, oldindan belgilangan scope lar. Hilt Google tomonidan barcha yangi Android loyihalari uchun tavsiya etiladi. Dagger dan Hilt ga migratsiya Component ni @InstallIn bilan almashtirishni, @Subcomponent ni oldindan belgilangan Hilt komponentlari bilan almashtirishni va qo'lda ViewModelProvider.Factory ni @HiltViewModel bilan almashtirishni o'z ichiga oladi. Aksariyat @Module sinflari @Provides metodlarini o'zgartirmasdan @InstallIn qo'shilishi bilan ko'chiriladi.
| Xususiyat | Dagger | Hilt |
|---|---|---|
| Sozlash | Qo'lda: Component, Subcomponent, Builder | Avtomatik: @HiltAndroidApp, @AndroidEntryPoint |
| Android komponentlari | Oldindan belgilangan yo'q | 12+ o'rnatilgan komponent |
| ViewModel | Qo'lda fabrika | @HiltViewModel + @Inject constructor |
| Ko'p modulli | @Component(dependencies) orqali | @InstallIn + agregatsiya orqali |
| Murakkablik | Yuqori — tajriba talab qiladi | Past — intuitiv |
| Moslashuvchanlik | Maksimal | Standart (95% stsenariyni qamrab oladi) |
Hilt cheklovlari: kutubxona faqat Android ni qo'llab-quvvatlaydi (sof server Java loyihalari uchun mos emas), ma'lum komponent tuzilishini majburlaydi (qayta yozish qiyin) va Jetpack Compose loyihalari uchun android.hilt:hilt-navigation-compose ga bog'liqlik qo'shadi. Compose ilovalari uchun Hilt hiltViewModel() orqali Composable da mavjud bo'lgan @HiltViewModel ni taqdim etadi — Activity dan ViewModel ni qo'lda taqdim etmasdan.
Tez-tez beriladigan savollar
Dagger — Component va Module ni qo'lda sozlash bilan asosiy kompilyatsiya vaqti DI freymvorki. Hilt — Android uchun qo'shimcha bo'lib, komponentlarni yaratish va Activity, Fragment, ViewModel, Service va BroadcastReceiver hayotiy tsikli bilan integratsiyani avtomatlashtiradi.
@HiltAndroidApp Application uchun Hilt komponentini yaratishni faollashtiradi. Ushbu annotatsiyasiz Hilt barcha ActivityComponent, FragmentComponent va ViewModelComponent meros oladigan asosiy SingletonComponent komponentini yarata olmaydi. Annotatsiya har bir Hilt loyihasi uchun majburiydir.
Hilt Navigation NavBackStackEntry dagi ViewModel uchun @HiltViewModel va navigatsiya grafi doirasida ViewModel ni skoplash uchun hiltNavGraphViewModels() ni taqdim etadi. android.hilt:hilt-navigation-fragment kutubxonasi har bir NavBackStackEntry uchun avtomatik ViewModel yaratadi.
Ilova konteksti uchun @ApplicationContext yoki Activity konteksti uchun @ActivityContext dan foydalaning. Hilt ushbu kvalifikatorlarni android.hilt:hilt-android kutubxonasida o'rnatilgan holda taqdim etadi. @ActivityContext faqat ActivityComponent da o'rnatilgan modullarda mavjud.
@Binds — metod aynan bitta parametrni qabul qilganda va uning turini interfeys sifatida qaytarganda @Provides ga samarali alternativadir. @Binds metodni chaqirmasdan to'g'ridan-to'g'ri cast yaratadi, bu yaratilgan kod miqdorini kamaytiradi va kiritish vaqtida ishlashni oshiradi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.