Hilt هي مكتبة لتوفير التبعيات في Android، وهي تقلّل من الرمز النموذجي اللازم لتوفير التبعيات يدويًا في مشروعك. يتطلّب تضمين التبعيات يدويًا إنشاء كل فئة وتبعياتها يدويًا، واستخدام الحاويات لإعادة استخدام التبعيات وإدارتها.
توفّر Hilt طريقة عادية لاستخدام ميزة "توفير التبعية" في تطبيقك من خلال توفير حاويات لكل فئة Android في مشروعك وإدارة مراحل نشاطها تلقائيًا. تم إنشاء Hilt استنادًا إلى مكتبة DI الشائعة Dagger للاستفادة من الصحة في وقت الترجمة والأداء في وقت التشغيل وقابلية التوسّع وتوافقها مع "استوديو Android" التي توفّرها Dagger. لمزيد من المعلومات، يُرجى الاطّلاع على Hilt وDagger.
يوضّح هذا الدليل المفاهيم الأساسية لـ Hilt والحاويات التي يتم إنشاؤها. ويتضمّن أيضًا عرضًا توضيحيًا لكيفية إعداد تطبيق حالي لاستخدام Hilt.
إضافة التبعيات
أولاً، أضِف المكوّن الإضافي hilt-android-gradle-plugin إلى ملف build.gradle الجذر الخاص بمشروعك:
Kotlin
plugins { ... id("com.google.dagger.hilt.android") version "2.57.1" apply false }
أنيق
plugins { ... id 'com.google.dagger.hilt.android' version '2.57.1' apply false }
بعد ذلك، طبِّق المكوّن الإضافي لنظام Gradle وأضِف هذه التبعيات في ملف app/build.gradle:
Kotlin
plugins { id("com.google.devtools.ksp") id("com.google.dagger.hilt.android") } android { ... } dependencies { implementation("com.google.dagger:hilt-android:2.57.1") ksp("com.google.dagger:hilt-android-compiler:2.57.1") }
أنيق
... plugins { id 'com.google.devtools.ksp' id 'com.google.dagger.hilt.android' } android { ... } dependencies { implementation "com.google.dagger:hilt-android:2.57.1" ksp "com.google.dagger:hilt-compiler:2.57.1" }
للتأكّد من إعداد مشروعك لاستخدام Java 17، وهو الإصدار المطلوب من Jetpack Compose وHilt، أضِف ما يلي إلى ملف app/build.gradle:
Kotlin
android { ... compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } }
أنيق
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } }
فئة تطبيق Hilt
يجب أن تحتوي جميع التطبيقات التي تستخدم Hilt على فئة
Application يتم إضافة التعليق التوضيحي @HiltAndroidApp إليها.
تؤدي إضافة @HiltAndroidApp إلى تشغيل عملية إنشاء الرموز البرمجية في Hilt، بما في ذلك صنف أساسي لتطبيقك يعمل كحاوية للاعتماديات على مستوى التطبيق.
@HiltAndroidApp class ExampleApplication : Application() { ... }
يتم ربط مكوّن Hilt الذي تم إنشاؤه بكائن Application، كما يوفّر له التبعيات. بالإضافة إلى ذلك، هو المكوّن الرئيسي للتطبيق، ما يعني أنّه يمكن للمكوّنات الأخرى الوصول إلى التبعيات التي يوفّرها.
إدخال التبعيات في فئات Android
بعد إعداد Hilt في فئة Application وتوفُّر مكوّن على مستوى التطبيق، يمكن أن يوفّر Hilt التبعيات لفئات Android الأخرى التي تتضمّن التعليق التوضيحي @AndroidEntryPoint:
@AndroidEntryPoint class ExampleActivity : ComponentActivity() { ... }
يتوافق Hilt حاليًا مع فئات Android التالية:
-
Application(باستخدام@HiltAndroidApp) -
ViewModel(باستخدام@HiltViewModel) ActivityServiceBroadcastReceiver
في Compose، لست بحاجة إلى إضافة تعليقات توضيحية إلى عناصر فردية قابلة للإنشاء. بدلاً من ذلك،
أضِف التعليق التوضيحي @AndroidEntryPoint إلى عنصر الجذر ComponentActivity. ويعمل هذا كإحدى نقاط الدخول إلى نظام DI في المخطط الهرمي لواجهة المستخدم بالكامل، ما يتيح لك الوصول إلى ViewModels التي تم إدخالها باستخدام Hilt مباشرةً من داخل الدوال القابلة للإنشاء.
تنشئ @AndroidEntryPoint أحد مكونات Hilt لكل فئة Android في مشروعك. يمكن أن تتلقّى هذه المكوّنات عناصر تابعة من فئاتها الرئيسية المعنية، كما هو موضّح في التسلسل الهرمي للمكوّنات.
للحصول على التبعيات من أحد المكوّنات، استخدِم التعليق التوضيحي @Inject لتنفيذ عملية إدخال الحقل:
@AndroidEntryPoint class ExampleActivity : ComponentActivity() { @Inject lateinit var analytics: AnalyticsAdapter ... }
يمكن أن تحتوي الفئات التي يدرجها Hilt على فئات أساسية أخرى تستخدم أيضًا الإدراج.
لا تحتاج هذه الفئات إلى التعليق التوضيحي @AndroidEntryPoint إذا كانت مجرّدة.
لمزيد من المعلومات حول الاستدعاء في إحدى مراحل النشاط التي يتم إدخال فئة Android فيها، راجِع مدد بقاء المكوّنات.
تحديد عمليات الربط في Hilt
لتنفيذ عملية إدخال الحقول، يحتاج Hilt إلى معرفة كيفية توفير مثيلات للتبعيات اللازمة من المكوّن المقابل. يحتوي الربط على المعلومات اللازمة لتوفير مثيلات من نوع ما كعنصر تابع.
إحدى طرق تقديم معلومات الربط إلى Hilt هي تضمين المعلمات في الدالة الإنشائية. استخدِم التعليق التوضيحي @Inject في الدالة الإنشائية لإحدى الفئات لإخبار Hilt بكيفية توفير مثيلات من هذه الفئة:
class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
تمثّل مَعلمات الدالة الإنشائية التي تمّت إضافة تعليقات توضيحية إليها في إحدى الفئات التبعيات الخاصة بهذه الفئة. في المثال، AnalyticsAdapter يعتمد على AnalyticsService. لذلك، يجب أن يعرف Hilt أيضًا كيفية توفير مثيلات من AnalyticsService.
وحدات Hilt
في بعض الأحيان، لا يمكن إدخال نوع من خلال الدالة الإنشائية. ويمكن أن يحدث ذلك لعدة أسباب. على سبيل المثال، لا يمكنك إدخال واجهة في الدالة الإنشائية. لا يمكنك أيضًا استخدام دالة إنشائية لإدخال نوع لا تملكه، مثل فئة من مكتبة خارجية. في هذه الحالات، يمكنك تزويد Hilt بمعلومات الربط باستخدام وحدات Hilt.
وحدة Hilt هي فئة تمّت إضافة التعليق التوضيحي @Module إليها. توفّر هذه السمة لـ Hilt تعليمات حول كيفية إنشاء مثيلات من الأنواع التي لا يمكن توفيرها من خلال إدخال البيانات في الدالة الإنشائية، مثل الواجهات أو الفئات التابعة لجهات خارجية. يجب أيضًا إضافة التعليق التوضيحي @InstallIn إلى كل وحدة لإخبار Hilt بفئة Android التي سيتم استخدام كل وحدة فيها أو تثبيتها فيها.
تتوفّر التبعيات التي تقدّمها في وحدات Hilt في جميع المكوّنات التي تم إنشاؤها والمرتبطة بفئة Android التي تثبّت فيها وحدة Hilt.
إدخال مثيلات الواجهة باستخدام @Binds
لنأخذ المثال AnalyticsService. إذا كان AnalyticsService واجهة،
لا يمكنك إدخالها في الدالة الإنشائية. بدلاً من ذلك، قدِّم إلى Hilt معلومات الربط
من خلال إنشاء دالة مجرّدة مزوّدة بالتعليق التوضيحي @Binds داخل
وحدة Hilt.
تخبر التعليق التوضيحي @Binds Hilt عن طريقة التنفيذ التي يجب استخدامها عندما يحتاج إلى توفير مثيل لواجهة.
توفّر الدالة التي تمّت إضافة التعليقات التوضيحية إليها المعلومات التالية إلى Hilt:
- يخبر نوع القيمة التي تم إرجاعها للدالة Hilt عن الواجهة التي توفّر الدالة مثيلاً لها.
- تخبر مَعلمة الدالة Hilt عن التنفيذ الذي يجب توفيره.
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 }
يتم وضع التعليق التوضيحي AnalyticsModule على وحدة Hilt لأنّك تريد أن يدرج Hilt هذه الاعتمادية في ExampleActivity.@InstallIn(ActivityComponent.class) تعني هذه التعليقات التوضيحية أنّ جميع التبعيات في AnalyticsModule متاحة في جميع أنشطة التطبيق.
توفير مثيلات باستخدام @Provides
ليست الواجهات هي الحالة الوحيدة التي لا يمكنك فيها إدخال نوع من خلال الدالة الإنشائية.
لا يمكن أيضًا استخدام ميزة "إدخال البيانات عبر الدالة الإنشائية" إذا لم تكن تملك الفئة لأنّها تأتي من مكتبة خارجية (مثل فئات Retrofit أو OkHttpClient أو قواعد بيانات Room)، أو إذا كان يجب إنشاء مثيلات باستخدام نمط الإنشاء.
لنأخذ المثال السابق. إذا لم تكن تملك فئة AnalyticsService بشكل مباشر، يمكنك إخبار Hilt بكيفية توفير مثيلات من هذا النوع من خلال إنشاء دالة داخل وحدة Hilt وإضافة التعليق التوضيحي @Provides إلى تلك الدالة.
توفّر الدالة التي تمّت إضافة التعليقات التوضيحية إليها المعلومات التالية إلى Hilt:
- يخبر نوع القيمة التي تم إرجاعها للدالة Hilt بنوع المثيلات التي توفّرها الدالة.
- تخبر مَعلمات الدالة Hilt بتبعيات النوع المقابل.
- يخبر نص الدالة Hilt بكيفية توفير مثيل للنوع المقابل. ينفِّذ Hilt نص الدالة في كل مرة يحتاج فيها إلى توفير مثيل من هذا النوع.
@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) } }
توفير عمليات ربط متعددة للنوع نفسه
في الحالات التي تحتاج فيها إلى أن يوفّر Hilt عمليات تنفيذ مختلفة للنوع نفسه كعناصر تابعة، عليك تزويد Hilt بربطات متعدّدة. يمكنك تحديد روابط متعددة للنوع نفسه باستخدام المؤهلات.
المحدِّد هو تعليق توضيحي تستخدمه لتحديد ربط معيّن لنوع ما عندما يكون لهذا النوع عمليات ربط متعدّدة محدّدة.
لنأخذ المثال التالي. إذا كنت بحاجة إلى اعتراض طلبات إلى AnalyticsService، يمكنك استخدام عنصر OkHttpClient مع معترِض. بالنسبة إلى الخدمات الأخرى، قد تحتاج إلى اعتراض المكالمات بطريقة مختلفة. في هذه الحالة، عليك إخبار Hilt بكيفية توفير عمليتَي تنفيذ مختلفتَين للنوع OkHttpClient.
أولاً، حدِّد المؤهلات التي ستستخدمها لإضافة تعليقات توضيحية إلى الطريقتَين @Binds أو @Provides:
@Qualifier @Retention(AnnotationRetention.BINARY) annotation class AuthInterceptorOkHttpClient @Qualifier @Retention(AnnotationRetention.BINARY) annotation class OtherInterceptorOkHttpClient
بعد ذلك، يحتاج Hilt إلى معرفة كيفية توفير مثيل للنوع الذي يتوافق مع كل مؤهّل. في هذه الحالة، يمكنك استخدام وحدة Hilt مع @Provides.
لكلتا الطريقتين نوع القيمة التي تم إرجاعها نفسه، ولكن تحدّد المؤهلات الطريقتين على أنّهما ربطتان مختلفتان:
@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() } }
يمكنك إدخال النوع المحدّد الذي تحتاجه من خلال إضافة تعليق توضيحي إلى الحقل أو المَعلمة باستخدام المؤهّل المناسب:
// 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: ComponentActivity() { @AuthInterceptorOkHttpClient @Inject lateinit var okHttpClient: OkHttpClient }
كأفضل ممارسة، إذا أضفت مؤهِّلاً إلى نوع، أضِف مؤهِّلات إلى جميع الطرق الممكنة لتوفير هذه التبعية. قد يؤدي ترك التنفيذ الأساسي أو الشائع بدون مؤهّل إلى حدوث أخطاء، وقد يتسبب في أن يحقن Hilt التبعية الخاطئة.
المؤهِّلات المحدَّدة مسبقًا في Hilt
توفّر Hilt بعض المؤهلات المحدّدة مسبقًا. على سبيل المثال، بما أنّك قد تحتاج إلى الفئة
Context من التطبيق أو النشاط، يوفّر Hilt المؤهّلين
@ApplicationContext و@ActivityContext.
لنفترض أنّ الفئة AnalyticsAdapter من المثال تحتاج إلى سياق النشاط. يوضّح الرمز التالي كيفية توفير سياق النشاط للدالة AnalyticsAdapter:
class AnalyticsAdapter @Inject constructor( @ActivityContext private val context: Context, private val service: AnalyticsService ) { ... }
للاطّلاع على عمليات الربط الأخرى المحدّدة مسبقًا والمتاحة في Hilt، يُرجى الرجوع إلى عمليات الربط التلقائية للمكوّنات.
المكوّنات التي تم إنشاؤها لفئات Android
لكل فئة Android يمكنك تنفيذ عملية إدخال الحقل فيها، هناك مكوّن Hilt مرتبط يمكنك الرجوع إليه في التعليق التوضيحي @InstallIn.
يكون كل مكوّن من مكوّنات Hilt مسؤولاً عن إدخال روابطه في فئة Android المناسبة.
توضّح الأمثلة السابقة استخدام ActivityComponent في وحدات Hilt.
توفّر مكتبة Hilt المكوّنات التالية:
| مكوِّن Hilt | أداة إدخال لـ |
|---|---|
SingletonComponent |
Application |
ActivityRetainedComponent |
لا ينطبق |
ViewModelComponent |
ViewModel |
ActivityComponent |
Activity |
ServiceComponent |
Service |
مدد صلاحية المكوّنات
ينشئ Hilt تلقائيًا مثيلات لفئات المكوّنات التي تم إنشاؤها ويزيلها باتّباع مراحل نشاط فئات Android المقابلة.
| المكوِّن الذي تم إنشاؤه | وقت الإنشاء: | تاريخ الإتلاف |
|---|---|---|
SingletonComponent |
Application#onCreate() |
Application destroyed |
ActivityRetainedComponent |
Activity#onCreate() |
Activity#onDestroy() |
ViewModelComponent |
تم إنشاء ViewModel. |
ViewModel destroyed |
ActivityComponent |
Activity#onCreate() |
Activity#onDestroy() |
ServiceComponent |
Service#onCreate() |
Service#onDestroy() |
نطاقات المكوّنات
تكون جميع عمليات الربط في Hilt غير محدودة النطاق تلقائيًا. وهذا يعني أنّه في كل مرة يطلب فيها تطبيقك الربط، ينشئ Hilt مثيلاً جديدًا من النوع المطلوب.
في المثال، في كل مرة يوفّر فيها Hilt AnalyticsAdapter كاعتمادية لنوع آخر أو من خلال إدخال حقل (كما في ExampleActivity)، يوفّر Hilt مثيلاً جديدًا من AnalyticsAdapter.
ومع ذلك، يتيح Hilt أيضًا تحديد نطاق الربط بمكوّن معيّن. لا ينشئ Hilt عملية ربط محدودة النطاق إلا مرة واحدة لكل مثيل من المكوّن الذي يتم تحديد نطاق عملية الربط فيه، وتتشارك جميع طلبات عملية الربط المثيل نفسه.
يسرد الجدول أدناه تعليقات توضيحية للنطاق لكل مكوّن تم إنشاؤه:
| فئة Android | المكوِّن الذي تم إنشاؤه | النطاق |
|---|---|---|
Application |
SingletonComponent |
@Singleton |
Activity |
ActivityRetainedComponent |
@ActivityRetainedScoped |
ViewModel |
ViewModelComponent |
@ViewModelScoped |
Activity |
ActivityComponent |
@ActivityScoped |
Service |
ServiceComponent |
@ServiceScoped |
في المثال، إذا حدّدت نطاق AnalyticsAdapter إلى ActivityComponent
باستخدام @ActivityScoped، يوفّر Hilt مثيلاً واحدًا من AnalyticsAdapter
طوال مدة نشاط التطبيق المقابل:
@ActivityScoped class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
لنفترض أنّ AnalyticsService يتضمّن حالة داخلية تتطلّب استخدام المثيل نفسه في كل مرة، وليس فقط في ExampleActivity، بل في أي مكان في التطبيق. في هذه الحالة، من المناسب تحديد نطاق AnalyticsService إلى SingletonComponent. والنتيجة هي أنّه كلما احتاج المكوّن إلى توفير مثيل من AnalyticsService، سيوفّر المثيل نفسه في كل مرة.
يوضّح المثال التالي كيفية تحديد نطاق ربط بمكوّن في وحدة Hilt. يجب أن يتطابق نطاق الربط مع نطاق المكوّن الذي تم تثبيته فيه، لذا في هذا المثال، يجب تثبيت AnalyticsService في SingletonComponent بدلاً من ActivityComponent:
// 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) } }
لمزيد من المعلومات عن نطاقات مكوّنات Hilt، يمكنك الاطّلاع على مقالة تحديد النطاق في Android وHilt.
التدرّج الهرمي للمكوّنات
يسمح تثبيت وحدة في أحد المكوّنات بالوصول إلى عمليات الربط الخاصة بها كاعتمادية لعمليات الربط الأخرى في هذا المكوّن أو في أي مكوّن ثانوي أسفله في التسلسل الهرمي للمكوّنات.
عمليات الربط التلقائية للمكوّنات
يأتي كل مكوّن من Hilt مزوّدًا بمجموعة من عمليات الربط التلقائية التي يمكن أن يدرجها Hilt كعناصر تابعة في عمليات الربط المخصّصة. يُرجى العِلم أنّ عمليات الربط هذه تتوافق مع نوع النشاط العام وليس مع أي فئة فرعية محدّدة. ويرجع ذلك إلى أنّ Hilt تستخدم تعريفًا واحدًا لمكوّن النشاط من أجل إدخال جميع الأنشطة. يحتوي كل نشاط على نسخة مختلفة من هذا المكوّن.
| مكوِّن Android | عمليات الربط التلقائية |
|---|---|
SingletonComponent |
Application |
ActivityRetainedComponent |
Application |
ViewModelComponent |
SavedStateHandle |
ActivityComponent |
Application، Activity |
ServiceComponent |
Application، Service |
يتوفّر ربط سياق التطبيق أيضًا باستخدام @ApplicationContext.
على سبيل المثال:
class AnalyticsServiceImpl @Inject constructor( @ApplicationContext context: Context ) : AnalyticsService { ... } // The Application binding is available without qualifiers. class AnalyticsServiceImpl @Inject constructor( application: Application ) : AnalyticsService { ... }
يمكن أيضًا استخدام ربط سياق النشاط باستخدام @ActivityContext. على سبيل المثال:
class AnalyticsAdapter @Inject constructor( @ActivityContext context: Context ) { ... } // The Activity binding is available without qualifiers. class AnalyticsAdapter @Inject constructor( activity: ComponentActivity ) { ... }
إدخال التبعيات في الفئات غير المتوافقة مع Hilt
في Compose، النمط العادي هو إدخال التبعيات في @HiltViewModel باستخدام ميزة "إدخال البيانات من خلال الدالة الإنشائية"، ثم استخدام hiltViewModel() داخل العنصر القابل للإنشاء للوصول إلى ViewModel. على الرغم من أنّ Hilt يتيح استخدام معظم فئات Android الشائعة، قد تظل تواجه فئات غير متوافقة تحتاج فيها إلى تنفيذ عملية إدخال الحقل.
في هذه الحالات، يمكنك إنشاء نقطة دخول باستخدام التعليق التوضيحي @EntryPoint. نقطة الدخول هي الحد الفاصل بين الرمز البرمجي الذي يديره Hilt والرمز البرمجي الذي لا يديره. وهي النقطة التي يدخل فيها الرمز البرمجي لأول مرة إلى الرسم البياني للعناصر التي يديرها Hilt. تسمح نقاط الدخول لـ Hilt باستخدام الرمز الذي لا يديره Hilt لتوفير التبعيات ضمن الرسم البياني للتبعيات.
على سبيل المثال، لا يتيح Hilt استخدام موفّري المحتوى مباشرةً. إذا أردت أن يستخدم موفّر المحتوى Hilt للحصول على بعض التبعيات، عليك تحديد واجهة مزوّدة بالتعليق التوضيحي @EntryPoint لكل نوع ربط تريده وتضمين مؤهّلات. بعد ذلك، أضِف @InstallIn لتحديد المكوّن الذي سيتم تثبيت نقطة الدخول فيه على النحو التالي:
class ExampleContentProvider : ContentProvider() { @EntryPoint @InstallIn(SingletonComponent::class) interface ExampleContentProviderEntryPoint { fun analyticsService(): AnalyticsService } ... }
للوصول إلى نقطة دخول، استخدِم الطريقة الثابتة المناسبة من EntryPointAccessors. يجب أن تكون المَعلمة إما مثيلاً للمكوّن أو الكائن @AndroidEntryPoint الذي يعمل كحاوية للمكوّن. تأكَّد من أنّ المكوّن الذي تمرّره كمَعلمة والطريقة الثابتة EntryPointAccessors يتطابقان مع فئة Android في التعليق التوضيحي @InstallIn على الواجهة @EntryPoint:
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() ... } }
في هذا المثال، يجب استخدام ApplicationContext لاسترداد نقطة الدخول لأنّها مثبّتة في SingletonComponent. إذا كان الربط الذي تريد استرداده في ActivityComponent، عليك استخدام ActivityContext بدلاً من ذلك.
Hilt وDagger
Hilt هي المكتبة التي يُنصح باستخدامها رسميًا لتوفير التبعية في Android. توفّر هذه المكتبة طريقة موحّدة وفعّالة ومحدّدة لتنفيذ ميزة "إدخال التبعية" في تطبيقك، وهي محسّنة خصيصًا لتوافقها مع Jetpack Compose وبنى التطبيقات ذات النشاط الواحد.
في ما يلي أهداف Hilt:
- لإنشاء مجموعة عادية من المكوّنات والنطاقات لتسهيل عملية الإعداد والقراءة ومشاركة الرموز البرمجية بين التطبيقات
- لتوفير طريقة سهلة لتوفير روابط مختلفة لأنواع إصدارات متعددة، مثل الإصدارات التجريبية أو إصدارات تصحيح الأخطاء أو الإصدارات العلنية
بما أنّ نظام التشغيل Android ينشئ العديد من فئات إطار العمل الخاص به، يتطلّب استخدام Dagger في تطبيق Android كتابة قدر كبير من الرموز النموذجية. يقلّل Hilt من رمز النص النموذجي المتضمّن في استخدام Dagger في تطبيق Android. تنشئ Hilt تلقائيًا وتوفّر ما يلي:
- مكوّنات لدمج فئات إطار عمل Android مع Dagger، والتي كان عليك إنشاؤها يدويًا.
- تعليقات توضيحية للنطاق لاستخدامها مع المكوّنات التي ينشئها Hilt تلقائيًا
- عمليات الربط المحدّدة مسبقًا لتمثيل فئات Android، مثل
ApplicationأوActivity - المؤهلات المحدّدة مسبقًا لتمثيل
@ApplicationContextو@ActivityContext
يمكن أن يتواجد رمز Dagger وHilt في قاعدة الرموز البرمجية نفسها. ومع ذلك، في معظم الحالات، من الأفضل استخدام Hilt لإدارة جميع استخداماتك لـ Dagger على Android. لنقل مشروع يستخدم Dagger إلى Hilt، راجِع دليل النقل.
مراجع إضافية
لمزيد من المعلومات حول Hilt، يُرجى الاطّلاع على المراجع الإضافية التالية.
نماذج
المدوّنات
- توفير التبعية في Android باستخدام Hilt
- تحديد النطاق في Android وHilt
- إضافة مكوّنات إلى التسلسل الهرمي في Hilt
- نقل تطبيق Google I/O إلى Hilt