Hilt, Android के लिए डिपेंडेंसी इंजेक्शन लाइब्रेरी है. यह बॉयलरप्लेट को कम करता है जिसमें मैन्युअल डिपेंडेंसी इंजेक्शन शामिल किया गया हो. मैन्युअल डिपेंडेंसी शुरू करें इंजेक्शन के लिए, आपको हर क्लास और उसकी डिपेंडेंसी को ध्यान में रखते हुए, और कंटेनर का दोबारा इस्तेमाल करने के लिए डिपेंडेंसी मैनेज करें.
Hilt, आपके ऐप्लिकेशन में डीआई का इस्तेमाल करने का स्टैंडर्ड तरीका मुहैया कराता है. इसके लिए, आपके प्रोजेक्ट की हर Android क्लास के लिए कंटेनर और उनके लाइफ़साइकल मैनेज करना स्वचालित रूप से. Hilt को मशहूर डीआई लाइब्रेरी के ऊपर बनाया गया है डैगर: कंपाइल-टाइम में सुधार, रनटाइम की परफ़ॉर्मेंस, स्केलेबिलिटी, और Android Studio सहायता जो डैगर उपलब्ध कराता है. ज़्यादा जानकारी के लिए, हिट और क्लिक करें डैगर.
यह गाइड, Hilt और इसके जनरेट किए गए कंटेनर के बुनियादी सिद्धांतों के बारे में जानकारी देती है. यह इसमें यह जानकारी भी शामिल है कि Hilt का इस्तेमाल करने के लिए, किसी मौजूदा ऐप्लिकेशन को बूटस्ट्रैप कैसे करें.
डिपेंडेंसी जोड़ना
सबसे पहले, अपने प्रोजेक्ट के रूट में hilt-android-gradle-plugin
प्लगिन जोड़ें
build.gradle
फ़ाइल:
ग्रूवी
plugins { ... id 'com.google.dagger.hilt.android' version '2.44' apply false }
Kotlin
plugins { ... id("com.google.dagger.hilt.android") version "2.44" apply false }
इसके बाद, Gradle प्लग इन लागू करें और इन डिपेंडेंसी को अपने
app/build.gradle
फ़ाइल:
ग्रूवी
... plugins { id 'kotlin-kapt' id 'com.google.dagger.hilt.android' } android { ... } dependencies { implementation "com.google.dagger:hilt-android:2.44" kapt "com.google.dagger:hilt-compiler:2.44" } // Allow references to generated code kapt { correctErrorTypes true }
Kotlin
plugins { id("kotlin-kapt") id("com.google.dagger.hilt.android") } android { ... } dependencies { implementation("com.google.dagger:hilt-android:2.44") kapt("com.google.dagger:hilt-android-compiler:2.44") } // Allow references to generated code kapt { correctErrorTypes = true }
Hilt, Java 8 की सुविधाओं का इस्तेमाल करता है. Java 8 को
app/build.gradle
फ़ाइल में यह जोड़ें:
ग्रूवी
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
Kotlin
android { ... compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }
हिल्ट ऐप्लिकेशन क्लास
Hilt का इस्तेमाल करने वाले सभी ऐप्लिकेशन में
Application
क्लास जिसके साथ एनोटेट किया गया है
@HiltAndroidApp
.
@HiltAndroidApp
, Hilt का कोड जनरेट करने की प्रोसेस ट्रिगर करता है. इसमें, इसके लिए बेस क्लास भी शामिल है
आपका ऐप्लिकेशन, जो ऐप्लिकेशन-लेवल डिपेंडेंसी कंटेनर के रूप में काम करता है.
Kotlin
@HiltAndroidApp class ExampleApplication : Application() { ... }
Java
@HiltAndroidApp public class ExampleApplication extends Application { ... }
जनरेट किया गया यह Hilt कॉम्पोनेंट Application
ऑब्जेक्ट के साथ अटैच है
लाइफ़साइकल होता है और यह इसके लिए डिपेंडेंसी देता है. इसके अलावा, यह पैरंट
का एक हिस्सा है, जिसका मतलब है कि अन्य कॉम्पोनेंट
निर्भर है जो यह उपलब्ध कराता है.
Android क्लास में डिपेंडेंसी इंजेक्ट करें
एक बार Hilt को आपकी Application
क्लास और ऐप्लिकेशन-लेवल में सेट अप कर दिया जाता है
कॉम्पोनेंट उपलब्ध है, तो Hilt अन्य Android क्लास के लिए डिपेंडेंसी दे सकता है
जिनमें @AndroidEntryPoint
एनोटेशन है:
Kotlin
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { ... }
Java
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { ... }
फ़िलहाल, Hilt इन Android क्लास के साथ काम करता है:
Application
(@HiltAndroidApp
का इस्तेमाल करके)ViewModel
(@HiltViewModel
का इस्तेमाल करके)Activity
Fragment
View
Service
BroadcastReceiver
अगर आपको @AndroidEntryPoint
की मदद से किसी Android क्लास के बारे में जानकारी देनी है, तो आपको ये काम भी करने होंगे
इस पर निर्भर Android क्लास के बारे में बताती हैं. उदाहरण के लिए, अगर आपके पास
फ़्रैगमेंट है, तो आपको उन सभी गतिविधियों के बारे में भी जानकारी देनी होगी जहां आप
फ़्रैगमेंट.
@AndroidEntryPoint
, हर Android के लिए अलग-अलग Hilt कॉम्पोनेंट जनरेट करता है
क्लास की शुरुआत की है. ये कॉम्पोनेंट, पब्लिशर के लिए
कॉम्पोनेंट में बताए गए, पैरंट क्लास के बारे में जानकारी
हैरारकी के हिसाब से खोजना है.
किसी कॉम्पोनेंट से डिपेंडेंसी पाने के लिए, @Inject
एनोटेशन का इस्तेमाल करें
फ़ील्ड इंजेक्शन:
Kotlin
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { @Inject lateinit var analytics: AnalyticsAdapter ... }
Java
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { @Inject AnalyticsAdapter analytics; ... }
Hilt इंजेक्ट करने वाली क्लास में अन्य बेस क्लास हो सकती हैं जिनमें इंजेक्शन का भी इस्तेमाल किया जाता है.
इन क्लास को @AndroidEntryPoint
एनोटेशन की ज़रूरत नहीं होती है, अगर वे
ऐब्सट्रैक्ट
Android क्लास को किस लाइफ़साइकल कॉलबैक में इंजेक्ट किया जाता है, इस बारे में ज़्यादा जानने के लिए, कॉम्पोनेंट लाइफ़टाइम देखें.
हिल्ट बाइंडिंग तय करें
फ़ील्ड इंजेक्शन के लिए, Hilt को यह जानने की ज़रूरत है कि यह काम करता है. बाइंडिंग में यह शामिल है डिपेंडेंसी के तौर पर किसी टाइप के इंस्टेंस देने के लिए ज़रूरी जानकारी.
Hilt को ज़रूरी जानकारी देने का एक तरीका कंस्ट्रक्टर इंजेक्शन है. इस्तेमाल की जाने वाली चीज़ें
Hilt को यह बताने के लिए कि क्लास के कंस्ट्रक्टर पर @Inject
एनोटेशन
उस क्लास के इंस्टेंस दें:
Kotlin
class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
Java
public class AnalyticsAdapter { private final AnalyticsService service; @Inject AnalyticsAdapter(AnalyticsService service) { this.service = service; } ... }
क्लास के एनोटेट किए गए कंस्ट्रक्टर के पैरामीटर, इसकी डिपेंडेंसी
उस क्लास को शामिल न करें. उदाहरण में, AnalyticsAdapter
के लिए AnalyticsService
निर्भर है. इसलिए, Hilt को यह भी पता होना चाहिए कि ऐसे मामले कैसे जोड़े जाएं
AnalyticsService
.
हिल्ट मॉड्यूल
कभी-कभी किसी टाइप को कंस्ट्रक्टर इंजेक्ट नहीं किया जा सकता. ऐसा कई मामलों में की वजह. उदाहरण के लिए, किसी इंटरफ़ेस को कंस्ट्रक्टर इंजेक्ट नहीं किया जा सकता. आपको यह भी किसी ऐसे टाइप का कंस्ट्रक्टर इंजेक्ट नहीं कर सकता जिसका मालिकाना हक आपके पास न हो, जैसे कि किसी बाहरी लाइब्रेरी का पता लगा सकते हैं. इन मामलों में, Hilt को ज़रूरी जानकारी के साथ उपलब्ध कराया जा सकता है Hilt मॉड्यूल का इस्तेमाल करके ऐसा किया जा सकता है.
Hilt मॉड्यूल ऐसी क्लास है जिसके लिए @Module
का इस्तेमाल किया गया है. किसी डैगर की तरह
मॉड्यूल है, तो
Hilt को कुछ खास तरह के इंस्टेंस उपलब्ध कराने का तरीका बताता है. डैगर मॉड्यूल से अलग,
आपको Hilt के बारे में बताने के लिए, Hilt के मॉड्यूल को @InstallIn
के साथ एनोटेट करना होगा
क्लास में हर मॉड्यूल का इस्तेमाल किया जाएगा या उसे इंस्टॉल किया जाएगा.
Hilt मॉड्यूल में दी जाने वाली डिपेंडेंसी वे कॉम्पोनेंट जो उस Android क्लास से जुड़े होते हैं जिसमें आपने हिल्ट मॉड्यूल.
@Binds की मदद से इंटरफ़ेस इंजेक्ट करें
AnalyticsService
के उदाहरण पर गौर करें. अगर AnalyticsService
एक इंटरफ़ेस है,
तो आप इसे कंस्ट्रक्टर-इंजेक्ट नहीं कर सकते. इसके बजाय, Hilt को बाइंडिंग उपलब्ध कराएं
@Binds
के साथ एनोटेट करके एक ऐब्स्ट्रैक्ट फ़ंक्शन बनाकर जानकारी
हिल्ट मॉड्यूल.
@Binds
एनोटेशन से Hilt को पता चलता है कि ज़रूरत पड़ने पर किस फ़ंक्शन का इस्तेमाल करना है
इंटरफ़ेस का एक इंस्टेंस दें.
व्याख्या किया गया फ़ंक्शन, Hilt को यह जानकारी देता है:
- फ़ंक्शन के रिटर्न टाइप से Hilt के बारे में जानकारी मिलती है कि फ़ंक्शन कौनसा इंटरफ़ेस देता है के उदाहरण.
- फ़ंक्शन पैरामीटर Hilt को बताता है कि कौनसा फ़ंक्शन देना है.
Kotlin
interface AnalyticsService { fun analyticsMethods() } // Constructor-injected, because Hilt needs to know how to // provide instances of AnalyticsServiceImpl, too. class AnalyticsServiceImpl @Inject constructor( ... ) : AnalyticsService { ... } @Module @InstallIn(ActivityComponent::class) abstract class AnalyticsModule { @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService }
Java
public interface AnalyticsService { void analyticsMethods(); } // Constructor-injected, because Hilt needs to know how to // provide instances of AnalyticsServiceImpl, too. public class AnalyticsServiceImpl implements AnalyticsService { ... @Inject AnalyticsServiceImpl(...) { ... } } @Module @InstallIn(ActivityComponent.class) public abstract class AnalyticsModule { @Binds public abstract AnalyticsService bindAnalyticsService( AnalyticsServiceImpl analyticsServiceImpl ); }
Hilt मॉड्यूल AnalyticsModule
के साथ एनोटेट किया गया है
@InstallIn(ActivityComponent.class)
क्योंकि आप चाहते हैं कि Hilt उसे इंजेक्ट करे
ExampleActivity
पर निर्भर है. इस एनोटेशन का मतलब है कि
AnalyticsModule
में डिपेंडेंसी, ऐप्लिकेशन की सभी गतिविधियों के लिए उपलब्ध है.
@Providers से इंस्टेंस इंजेक्ट करें
इंटरफ़ेस ही सिर्फ़ ऐसा मामला नहीं है जिसमें किसी टाइप को कंस्ट्रक्टर इंजेक्ट नहीं किया जा सकता.
अगर आप क्लास के मालिक नहीं हैं, तो भी कंस्ट्रक्टर इंजेक्शन नहीं किया जा सकता, क्योंकि
एक बाहरी लाइब्रेरी से आता है (क्लास
Retrofit,
OkHttpClient
,
या रूम डेटाबेस) या अगर इंस्टेंस ज़रूरी हैं
बिल्डर की सहायता से बनाए जाएं
पैटर्न.
ऊपर दिए गए उदाहरण पर गौर करें. अगर आपके पास सीधे तौर पर AnalyticsService
का मालिकाना हक नहीं है
क्लास में है, तो आप एक
फ़ंक्शन को एक Hilt मॉड्यूल के अंदर इकट्ठा करता है और उस फ़ंक्शन की @Provides
के साथ व्याख्या करता है.
व्याख्या किया गया फ़ंक्शन, Hilt को यह जानकारी उपलब्ध कराता है:
- फ़ंक्शन के रिटर्न टाइप से Hilt के बारे में पता चलता है कि फ़ंक्शन किस टाइप के इंस्टेंस देता है में से.
- फ़ंक्शन पैरामीटर, इससे जुड़े टाइप की डिपेंडेंसी को Hilt के बारे में बताते हैं.
- फ़ंक्शन का मुख्य हिस्सा, Hilt को इससे जुड़ा एक इंस्टेंस देने का तरीका बताता है टाइप करें. Hilt, फ़ंक्शन को हर बार कार्रवाई करने के लिए एक्ज़ीक्यूट करता है दर्ज करें.
Kotlin
@Module @InstallIn(ActivityComponent::class) object AnalyticsModule { @Provides fun provideAnalyticsService( // Potential dependencies of this type ): AnalyticsService { return Retrofit.Builder() .baseUrl("https://example.com") .build() .create(AnalyticsService::class.java) } }
Java
@Module @InstallIn(ActivityComponent.class) public class AnalyticsModule { @Provides public static AnalyticsService provideAnalyticsService( // Potential dependencies of this type ) { return new Retrofit.Builder() .baseUrl("https://example.com") .build() .create(AnalyticsService.class); } }
एक ही टाइप के लिए एक से ज़्यादा बाइंडिंग उपलब्ध कराएं
ऐसे मामलों में जहां आपको Hilt की ज़रूरत है, ताकि आप उसे अलग-अलग तरीके से लागू कर सकें टाइप करना होगा, तो आपको Hilt को एक से ज़्यादा बाइंडिंग के साथ उपलब्ध कराना होगा. आप क्वालिफ़ायर की मदद से, एक ही टाइप के लिए एक से ज़्यादा बाइंडिंग तय करें.
क्वालीफ़ायर वह जानकारी होती है जिसका इस्तेमाल किसी टाइप करें, जब उस टाइप की एक से ज़्यादा बाइंडिंग हों.
उदाहरण पर ध्यान दें. अगर आपको AnalyticsService
पर आने वाले कॉल को रोकना है, तो
एक OkHttpClient
ऑब्जेक्ट का इस्तेमाल
इंटरसेप्टर होना चाहिए. इसके लिए
कॉल को किसी अन्य तरीके से रोकना पड़ सकता है. इसमें
केस में, आपको Hilt को यह बताना होगा कि वे
OkHttpClient
.
सबसे पहले, उन क्वालिफ़ायर के बारे में बताएं जिनका इस्तेमाल आपको @Binds
के बारे में बताने के लिए करना है या
@Provides
तरीके:
Kotlin
@Qualifier @Retention(AnnotationRetention.BINARY) annotation class AuthInterceptorOkHttpClient @Qualifier @Retention(AnnotationRetention.BINARY) annotation class OtherInterceptorOkHttpClient
Java
@Qualifier @Retention(RetentionPolicy.RUNTIME) private @interface AuthInterceptorOkHttpClient {} @Qualifier @Retention(RetentionPolicy.RUNTIME) private @interface OtherInterceptorOkHttpClient {}
इसके बाद, Hilt को यह जानने की ज़रूरत है कि उस टाइप का इंस्टेंस कैसे दिया जाए जो
हर क्वालीफ़ायर के साथ. इस मामले में, @Provides
के साथ Hilt मॉड्यूल का इस्तेमाल किया जा सकता है.
दोनों तरीकों में रिटर्न टाइप एक ही होता है, लेकिन क्वालीफ़ायर उन्हें दो के तौर पर लेबल करता है
अलग-अलग बाइंडिंग:
Kotlin
@Module @InstallIn(SingletonComponent::class) object NetworkModule { @AuthInterceptorOkHttpClient @Provides fun provideAuthInterceptorOkHttpClient( authInterceptor: AuthInterceptor ): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(authInterceptor) .build() } @OtherInterceptorOkHttpClient @Provides fun provideOtherInterceptorOkHttpClient( otherInterceptor: OtherInterceptor ): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(otherInterceptor) .build() } }
Java
@Module @InstallIn(ActivityComponent.class) public class NetworkModule { @AuthInterceptorOkHttpClient @Provides public static OkHttpClient provideAuthInterceptorOkHttpClient( AuthInterceptor authInterceptor ) { return new OkHttpClient.Builder() .addInterceptor(authInterceptor) .build(); } @OtherInterceptorOkHttpClient @Provides public static OkHttpClient provideOtherInterceptorOkHttpClient( OtherInterceptor otherInterceptor ) { return new OkHttpClient.Builder() .addInterceptor(otherInterceptor) .build(); } }
अपनी ज़रूरत के हिसाब से कोई खास टाइप डालने के लिए, फ़ील्ड की जानकारी दें या मिलते-जुलते क्वालीफ़ायर के साथ पैरामीटर:
Kotlin
// As a dependency of another class. @Module @InstallIn(ActivityComponent::class) object AnalyticsModule { @Provides fun provideAnalyticsService( @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient ): AnalyticsService { return Retrofit.Builder() .baseUrl("https://example.com") .client(okHttpClient) .build() .create(AnalyticsService::class.java) } } // As a dependency of a constructor-injected class. class ExampleServiceImpl @Inject constructor( @AuthInterceptorOkHttpClient private val okHttpClient: OkHttpClient ) : ... // At field injection. @AndroidEntryPoint class ExampleActivity: AppCompatActivity() { @AuthInterceptorOkHttpClient @Inject lateinit var okHttpClient: OkHttpClient }
Java
// As a dependency of another class. @Module @InstallIn(ActivityComponent.class) public class AnalyticsModule { @Provides public static AnalyticsService provideAnalyticsService( @AuthInterceptorOkHttpClient OkHttpClient okHttpClient ) { return new Retrofit.Builder() .baseUrl("https://example.com") .client(okHttpClient) .build() .create(AnalyticsService.class); } } // As a dependency of a constructor-injected class. public class ExampleServiceImpl ... { private final OkHttpClient okHttpClient; @Inject ExampleServiceImpl(@AuthInterceptorOkHttpClient OkHttpClient okHttpClient) { this.okHttpClient = okHttpClient; } } // At field injection. @AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { @AuthInterceptorOkHttpClient @Inject OkHttpClient okHttpClient; ... }
सबसे सही तरीका यह है कि अगर किसी टाइप में क्वालीफ़ायर जोड़ा जाता है, तो की अनुमति देता है. बेस या आम को छोड़ना क्वालीफ़ायर के बिना लागू करने पर गड़बड़ी की संभावना होती है और इससे Hilt हो सकता है गलत डिपेंडेंसी डालना.
Hilt में पहले से तय क्वालीफ़ायर
Hilt, पहले से तय किए गए कुछ क्वालिफ़ायर देता है. उदाहरण के लिए, आपको अभी इसकी ज़रूरत पड़ सकती है
ऐप्लिकेशन या गतिविधि से Context
क्लास, Hilt यह जानकारी देता है
@ApplicationContext
और @ActivityContext
क्वालिफ़ायर.
मान लें कि उदाहरण की AnalyticsAdapter
क्लास को
गतिविधि. इस कोड में, गतिविधि की जानकारी देने का तरीका बताया गया है
AnalyticsAdapter
के लिए संदर्भ:
Kotlin
class AnalyticsAdapter @Inject constructor( @ActivityContext private val context: Context, private val service: AnalyticsService ) { ... }
Java
public class AnalyticsAdapter { private final Context context; private final AnalyticsService service; @Inject AnalyticsAdapter( @ActivityContext Context context, AnalyticsService service ) { this.context = context; this.service = service; } }
Hilt में उपलब्ध अन्य पहले से तय बाइंडिंग के लिए, घटक डिफ़ॉल्ट देखें बाइंडिंग.
Android क्लास के लिए जनरेट किए गए कॉम्पोनेंट
हर उस Android क्लास के लिए जिसमें फ़ील्ड इंजेक्शन लिया जा सकता है,
असोसिएटेड हिल्ट कॉम्पोनेंट, जिसे @InstallIn
एनोटेशन में देखा जा सकता है.
हर Hilt कॉम्पोनेंट, अपनी बाइंडिंग को
संबंधित Android क्लास.
पिछले उदाहरणों में, Hilt में ActivityComponent
के इस्तेमाल के बारे में बताया गया है
मॉड्यूल देखें.
Hilt में ये कॉम्पोनेंट हैं:
हिलने वाला कॉम्पोनेंट | इंजेक्टर |
---|---|
SingletonComponent |
Application |
ActivityRetainedComponent |
लागू नहीं |
ViewModelComponent |
ViewModel |
ActivityComponent |
Activity |
FragmentComponent |
Fragment |
ViewComponent |
View |
ViewWithFragmentComponent |
View ने @WithFragmentBindings की व्याख्या की |
ServiceComponent |
Service |
कॉम्पोनेंट की लाइफ़टाइम गतिविधि
Hilt, जनरेट किए गए कॉम्पोनेंट क्लास के इंस्टेंस बनाता और खत्म करता है नीचे दिए गए चरण पूरे करने के लिए, ज़रूरी डेटा इकट्ठा किया जा सकता है.
जनरेट किया गया कॉम्पोनेंट | मैसेज किस समय लिखा गया | इस पर नष्ट किया गया |
---|---|---|
SingletonComponent |
Application#onCreate() |
Application खत्म किया गया |
ActivityRetainedComponent |
Activity#onCreate() |
Activity#onDestroy() |
ViewModelComponent |
ViewModel बनाया गया |
ViewModel खत्म किया गया |
ActivityComponent |
Activity#onCreate() |
Activity#onDestroy() |
FragmentComponent |
Fragment#onAttach() |
Fragment#onDestroy() |
ViewComponent |
View#super() |
View खत्म किया गया |
ViewWithFragmentComponent |
View#super() |
View खत्म किया गया |
ServiceComponent |
Service#onCreate() |
Service#onDestroy() |
कॉम्पोनेंट के स्कोप
डिफ़ॉल्ट रूप से, Hilt में सभी बाइंडिंग बिना स्कोप वाली होती हैं. इसका मतलब है कि हर बार आपके ऐप्लिकेशन बाइंडिंग का अनुरोध करता है, तो Hilt ज़रूरी टाइप का एक नया इंस्टेंस बनाता है.
इस उदाहरण में, जब भी Hilt, AnalyticsAdapter
को डिपेंडेंसी के तौर पर इस पर निर्भर करता है
किसी अन्य टाइप या फ़ील्ड इंजेक्शन (जैसा कि ExampleActivity
में है) के ज़रिए, Hilt उपलब्ध कराता है
AnalyticsAdapter
का नया इंस्टेंस.
हालांकि, Hilt, बाइंडिंग को किसी खास कॉम्पोनेंट तक के दायरे में लाने की अनुमति भी देता है. हिल्ट उस कॉम्पोनेंट के हर इंस्टेंस के लिए सिर्फ़ एक बार स्कोप वाली बाइंडिंग बनाता है जिसका इस्तेमाल करके बाइंडिंग का दायरा तक सीमित है और बाइंडिंग के लिए सभी अनुरोध एक ही इंस्टेंस शेयर करते हैं.
नीचे दी गई टेबल में, जनरेट किए गए हर कॉम्पोनेंट के लिए स्कोप एनोटेशन की सूची दी गई है:
Android क्लास | जनरेट किया गया कॉम्पोनेंट | दायरा |
---|---|---|
Application |
SingletonComponent |
@Singleton |
Activity |
ActivityRetainedComponent |
@ActivityRetainedScoped |
ViewModel |
ViewModelComponent |
@ViewModelScoped |
Activity |
ActivityComponent |
@ActivityScoped |
Fragment |
FragmentComponent |
@FragmentScoped |
View |
ViewComponent |
@ViewScoped |
View ने @WithFragmentBindings की व्याख्या की |
ViewWithFragmentComponent |
@ViewScoped |
Service |
ServiceComponent |
@ServiceScoped |
इस उदाहरण में, अगर AnalyticsAdapter
को ActivityComponent
तक सीमित किया गया है
@ActivityScoped
का इस्तेमाल करने पर, Hilt AnalyticsAdapter
का वही इंस्टेंस देता है
की अवधि के हिसाब से:
Kotlin
@ActivityScoped class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
Java
@ActivityScoped public class AnalyticsAdapter { private final AnalyticsService service; @Inject AnalyticsAdapter(AnalyticsService service) { this.service = service; } ... }
मान लें कि AnalyticsService
में एक अंदरूनी स्थिति है, जिसे
इंस्टेंस हर बार इस्तेमाल करना चाहिए—सिर्फ़ ExampleActivity
में ही नहीं, बल्कि
ऐप खोलें. इस मामले में, AnalyticsService
का दायरा
SingletonComponent
. इसका नतीजा यह होता है कि जब भी कॉम्पोनेंट को
AnalyticsService
का एक इंस्टेंस दें, यह हर बार समान इंस्टेंस देता है
समय.
नीचे दिए गए उदाहरण में, एक कॉम्पोनेंट में बाइंडिंग का दायरा बढ़ाने का तरीका बताया गया है.
हिल्ट मॉड्यूल. बाइंडिंग का स्कोप, कॉम्पोनेंट के स्कोप से मेल खाना चाहिए, जहां यह
इंस्टॉल किया है, इसलिए इस उदाहरण में आपको AnalyticsService
को
ActivityComponent
के बजाय SingletonComponent
:
Kotlin
// If AnalyticsService is an interface. @Module @InstallIn(SingletonComponent::class) abstract class AnalyticsModule { @Singleton @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService } // If you don't own AnalyticsService. @Module @InstallIn(SingletonComponent::class) object AnalyticsModule { @Singleton @Provides fun provideAnalyticsService(): AnalyticsService { return Retrofit.Builder() .baseUrl("https://example.com") .build() .create(AnalyticsService::class.java) } }
Java
// If AnalyticsService is an interface. @Module @InstallIn(SingletonComponent.class) public abstract class AnalyticsModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( AnalyticsServiceImpl analyticsServiceImpl ); } // If you don't own AnalyticsService. @Module @InstallIn(SingletonComponent.class) public class AnalyticsModule { @Singleton @Provides public static AnalyticsService provideAnalyticsService() { return new Retrofit.Builder() .baseUrl("https://example.com") .build() .create(AnalyticsService.class); } }
Hilt के कॉम्पोनेंट के स्कोप के बारे में ज़्यादा जानने के लिए, Android में स्कोप करना और हिलना.
कॉम्पोनेंट की हैरारकी
किसी कॉम्पोनेंट में मॉड्यूल इंस्टॉल करने से, इसकी बाइंडिंग को उस कॉम्पोनेंट या नीचे दिए गए किसी भी चाइल्ड कॉम्पोनेंट में, अन्य बाइंडिंग की डिपेंडेंसी इसे कॉम्पोनेंट की हैरारकी में:
कॉम्पोनेंट की डिफ़ॉल्ट बाइंडिंग
Hilt का हर कॉम्पोनेंट, डिफ़ॉल्ट बाइंडिंग के एक सेट के साथ आता है. इसे Hilt इस तौर पर इंजेक्ट कर सकता है डिपेंडेंसी को अपनी कस्टम बाइंडिंग में डालें. ध्यान दें कि ये बाइंडिंग मेल खाती हैं सामान्य गतिविधि और फ़्रैगमेंट टाइप के साथ-साथ किसी खास सब-क्लास के लिए भी इस्तेमाल किया जा सकता है. ऐसा इसलिए है, क्योंकि Hilt एक गतिविधि वाले कॉम्पोनेंट की परिभाषा का इस्तेमाल करके सभी को इंजेक्ट करता है गतिविधियां. हर गतिविधि में इस कॉम्पोनेंट का अलग-अलग इंस्टेंस होता है.
Android घटक | डिफ़ॉल्ट बाइंडिंग |
---|---|
SingletonComponent |
Application |
ActivityRetainedComponent |
Application |
ViewModelComponent |
SavedStateHandle |
ActivityComponent |
Application , Activity |
FragmentComponent |
Application , Activity , Fragment |
ViewComponent |
Application , Activity , View |
ViewWithFragmentComponent |
Application , Activity , Fragment , View |
ServiceComponent |
Application , Service |
@ApplicationContext
का इस्तेमाल करके भी ऐप्लिकेशन कॉन्टेक्स्ट बाइंडिंग उपलब्ध है.
उदाहरण के लिए:
Kotlin
class AnalyticsServiceImpl @Inject constructor( @ApplicationContext context: Context ) : AnalyticsService { ... } // The Application binding is available without qualifiers. class AnalyticsServiceImpl @Inject constructor( application: Application ) : AnalyticsService { ... }
Java
public class AnalyticsServiceImpl implements AnalyticsService { private final Context context; @Inject AnalyticsAdapter(@ApplicationContext Context context) { this.context = context; } } // The Application binding is available without qualifiers. public class AnalyticsServiceImpl implements AnalyticsService { private final Application application; @Inject AnalyticsAdapter(Application application) { this.application = application; } }
@ActivityContext
का इस्तेमाल करने पर, गतिविधि कॉन्टेक्स्ट बाइंडिंग भी उपलब्ध है. इसके लिए
उदाहरण:
Kotlin
class AnalyticsAdapter @Inject constructor( @ActivityContext context: Context ) { ... } // The Activity binding is available without qualifiers. class AnalyticsAdapter @Inject constructor( activity: FragmentActivity ) { ... }
Java
public class AnalyticsAdapter { private final Context context; @Inject AnalyticsAdapter(@ActivityContext Context context) { this.context = context; } } // The Activity binding is available without qualifiers. public class AnalyticsAdapter { private final FragmentActivity activity; @Inject AnalyticsAdapter(FragmentActivity activity) { this.activity = activity; } }
उन क्लास में डिपेंडेंसी इंजेक्ट करें जो Hilt के साथ काम नहीं करती हैं
Hilt, सबसे आम Android क्लास के साथ काम करता है. हालांकि, आपको ऐसी क्लास में फ़ील्ड इंजेक्शन लेने की ज़रूरत है जो Hilt के साथ काम नहीं करता.
ऐसे मामलों में, @EntryPoint
का इस्तेमाल करके एंट्री पॉइंट बनाया जा सकता है
एनोटेशन. एंट्री पॉइंट, कोड के बीच की सीमा होती है. इसे Hilt की मदद से मैनेज किया जाता है
और कई कोड हैं. यह वह बिंदु है जहां कोड सबसे पहले
ऐसी ऑब्जेक्ट हैं जिन्हें Hilt प्रबंधित करता है. एंट्री पॉइंट, Hilt के लिए उस कोड का इस्तेमाल करने की अनुमति देते हैं जो Hilt करता है
डिपेंडेंसी ग्राफ़ में डिपेंडेंसी देने के लिए मैनेज नहीं किया जा सकता.
उदाहरण के लिए, Hilt सीधे तौर पर कॉन्टेंट के साथ काम नहीं करता
सेवा देने वाली कंपनियां. अगर आपको कोई कॉन्टेंट चाहिए
प्रोवाइडर को Hilt का इस्तेमाल करने की ज़रूरत है. इसके लिए, आपको एक इंटरफ़ेस
जिसे आपकी पसंद के हर बाइंडिंग टाइप के लिए @EntryPoint
के साथ एनोटेट किया गया हो और
क्वालिफ़ायर शामिल होते हैं. इसके बाद, उस कॉम्पोनेंट के बारे में बताने के लिए @InstallIn
जोड़ें जिसमें
एंट्री पॉइंट को इस तरह इंस्टॉल करें:
Kotlin
class ExampleContentProvider : ContentProvider() { @EntryPoint @InstallIn(SingletonComponent::class) interface ExampleContentProviderEntryPoint { fun analyticsService(): AnalyticsService } ... }
Java
public class ExampleContentProvider extends ContentProvider { @EntryPoint @InstallIn(SingletonComponent.class) interface ExampleContentProviderEntryPoint { public AnalyticsService analyticsService(); } ... }
किसी एंट्री पॉइंट को ऐक्सेस करने के लिए,
EntryPointAccessors
. पैरामीटर या तो कॉम्पोनेंट इंस्टेंस होना चाहिए या
@AndroidEntryPoint
ऑब्जेक्ट, जो कॉम्पोनेंट होल्डर के तौर पर काम करता है. पक्का करें कि
पैरामीटर के तौर पर पास किया गया कॉम्पोनेंट और EntryPointAccessors
स्टैटिक
वे दोनों @InstallIn
एनोटेशन में Android क्लास से मेल खाते हैं
@EntryPoint
इंटरफ़ेस:
Kotlin
class ExampleContentProvider: ContentProvider() { ... override fun query(...): Cursor { val appContext = context?.applicationContext ?: throw IllegalStateException() val hiltEntryPoint = EntryPointAccessors.fromApplication(appContext, ExampleContentProviderEntryPoint::class.java) val analyticsService = hiltEntryPoint.analyticsService() ... } }
Java
public class ExampleContentProvider extends ContentProvider { @Override public Cursor query(...) { Context appContext = getContext().getApplicationContext(); ExampleContentProviderEntryPoint hiltEntryPoint = EntryPointAccessors.fromApplication(appContext, ExampleContentProviderEntryPoint.class); AnalyticsService analyticsService = hiltEntryPoint.analyticsService(); } }
इस उदाहरण में, एंट्री वापस पाने के लिए, आपको ApplicationContext
का इस्तेमाल करना होगा
पॉइंट, क्योंकि SingletonComponent
में एंट्री पॉइंट इंस्टॉल किया गया है. अगर
बाइंडिंग जिसे आप वापस पाना चाहते थे, वह ActivityComponent
में थी, तो आप
इसके बजाय ActivityContext
का इस्तेमाल करें.
हिल्ट ऐंड डैगर
हिल्ट, डैगर के ऊपर बना है डिपेंडेंसी इंजेक्शन लाइब्रेरी, डैगर को शामिल करने का स्टैंडर्ड तरीका देती है Android ऐप्लिकेशन में बदल सकते हैं.
डैगर के संबंध में, Hilt के लक्ष्य इस तरह हैं:
- Android ऐप्लिकेशन के लिए डैगर से जुड़े इन्फ़्रास्ट्रक्चर को आसान बनाने के लिए.
- आसानी से सेटअप और आसानी से समझने के लिए, कॉम्पोनेंट और स्कोप का स्टैंडर्ड सेट बनाने के लिए, और ऐप्लिकेशन के बीच कोड शेयर करना.
- अलग-अलग बिल्ड टाइप में अलग-अलग बाइंडिंग का प्रावधान करने का आसान तरीका देने के लिए, जैसे, टेस्टिंग, डीबग या रिलीज़.
ऐसा इसलिए, क्योंकि Android ऑपरेटिंग सिस्टम अपने कई फ़्रेमवर्क को इंस्टैंशिएट करता है क्लास में, Android ऐप्लिकेशन में डैगर का इस्तेमाल करने के लिए, आपको बॉयलरप्लेट की मात्रा. हिल्ट उस बॉयलरप्लेट कोड को कम कर देता है जो इसमें शामिल है Android ऐप्लिकेशन में डैगर का इस्तेमाल करके. Hilt अपने-आप जनरेट होता है और यह जानकारी उपलब्ध कराता है:
- डैगर के साथ Android फ़्रेमवर्क क्लास को इंटिग्रेट करने के लिए कॉम्पोनेंट नहीं तो मैन्युअल तरीके से बनाने पड़ते थे.
- Hilt के जनरेट किए गए कॉम्पोनेंट के साथ इस्तेमाल करने के लिए स्कोप की जानकारी स्वचालित रूप से.
Application
या Android क्लास जैसी Android क्लास को दिखाने के लिए पहले से तय बाइंडिंगActivity
.@ApplicationContext
और को दर्शाने के लिए पहले से तय क्वालीफ़ायर@ActivityContext
.
डैगर और हिल्ट कोड, एक ही कोड बेस में एक साथ रह सकते हैं. हालांकि, ज़्यादातर मामलों में Android पर डैगर के इस्तेमाल को मैनेज करने के लिए, Hilt का इस्तेमाल करें. माइग्रेट करने के लिए डैगर टू हिल्ट का इस्तेमाल करने वाला प्रोजेक्ट है, तो माइग्रेशन देखें गाइड और माइग्रेट करने की सुविधा Hilt के लिए आपका डैगर ऐप्लिकेशन कोडलैब (कोड बनाना सीखना).
अन्य संसाधन
Hilt के बारे में ज़्यादा जानने के लिए, नीचे दिए गए अतिरिक्त संसाधन देखें.
सैंपल
कोड लैब
ब्लॉग
- Android पर डिपेंडेंसी इंजेक्शन हिलना
- Android और Android में हिलना
- हिट में कॉम्पोनेंट जोड़ना क्रम
- Google I/O ऐप्लिकेशन को माइग्रेट करना हिलना