Hilt یک کتابخانه تزریق وابستگی برای اندروید است که دیگ بخار انجام تزریق وابستگی دستی در پروژه شما را کاهش می دهد. انجام تزریق وابستگی دستی به شما نیاز دارد که هر کلاس و وابستگیهای آن را با دست بسازید و از کانتینرها برای استفاده مجدد و مدیریت وابستگیها استفاده کنید.
Hilt با ارائه کانتینرهایی برای هر کلاس Android در پروژه شما و مدیریت چرخه عمر آنها به طور خودکار، راه استانداردی برای استفاده از DI در برنامه شما ارائه می دهد. Hilt بر روی کتابخانه محبوب DI Dagger ساخته شده است تا از صحت زمان کامپایل، عملکرد زمان اجرا، مقیاس پذیری و پشتیبانی از Android Studio که Dagger ارائه می کند بهره مند شود. برای اطلاعات بیشتر، به Hilt and Dagger مراجعه کنید.
این راهنما مفاهیم اساسی هیلت و کانتینرهای تولید شده آن را توضیح می دهد. همچنین شامل نمایشی از نحوه بوت استرپ کردن یک برنامه موجود برای استفاده از Hilt است.
افزودن وابستگی ها
ابتدا افزونه hilt-android-gradle-plugin
را به فایل root build.gradle
پروژه خود اضافه کنید:
شیار
plugins { ... id 'com.google.dagger.hilt.android' version '2.51.1' apply false }
کاتلین
plugins { ... id("com.google.dagger.hilt.android") version "2.51.1" 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.51.1" kapt "com.google.dagger:hilt-compiler:2.51.1" } // Allow references to generated code kapt { correctErrorTypes true }
کاتلین
plugins { id("kotlin-kapt") id("com.google.dagger.hilt.android") } android { ... } dependencies { implementation("com.google.dagger:hilt-android:2.51.1") kapt("com.google.dagger:hilt-android-compiler:2.51.1") } // Allow references to generated code kapt { correctErrorTypes = true }
Hilt از ویژگی های جاوا 8 استفاده می کند. برای فعال کردن جاوا 8 در پروژه خود، موارد زیر را به فایل app/build.gradle
اضافه کنید:
شیار
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
کاتلین
android { ... compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }
کلاس اپلیکیشن هیلت
همه برنامههایی که از Hilt استفاده میکنند باید دارای یک کلاس Application
باشند که با @HiltAndroidApp
حاشیهنویسی شده است.
@HiltAndroidApp
تولید کد Hilt را فعال می کند، از جمله یک کلاس پایه برای برنامه شما که به عنوان محفظه وابستگی در سطح برنامه عمل می کند.
کاتلین
@HiltAndroidApp class ExampleApplication : Application() { ... }
جاوا
@HiltAndroidApp public class ExampleApplication extends Application { ... }
این مؤلفه Hilt تولید شده به چرخه حیات شیء Application
متصل است و وابستگی هایی به آن ارائه می دهد. علاوه بر این، این جزء اصلی برنامه است، به این معنی که سایر مؤلفهها میتوانند به وابستگیهایی که ارائه میکند دسترسی داشته باشند.
وابستگی ها را به کلاس های اندروید تزریق کنید
هنگامی که Hilt در کلاس Application
شما راهاندازی شد و یک مؤلفه در سطح برنامه در دسترس قرار گرفت، Hilt میتواند وابستگیهایی را به سایر کلاسهای Android که حاشیهنویسی @AndroidEntryPoint
دارند ارائه دهد:
کاتلین
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { ... }
جاوا
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { ... }
Hilt در حال حاضر از کلاس های اندروید زیر پشتیبانی می کند:
-
Application
(با استفاده از@HiltAndroidApp
) -
ViewModel
(با استفاده از@HiltViewModel
) -
Activity
-
Fragment
-
View
-
Service
-
BroadcastReceiver
اگر یک کلاس Android را با @AndroidEntryPoint
حاشیه نویسی می کنید، باید کلاس های Android را که به آن وابسته هستند نیز حاشیه نویسی کنید. برای مثال، اگر یک قطعه را حاشیه نویسی می کنید، باید هر فعالیتی را که از آن قطعه استفاده می کنید نیز حاشیه نویسی کنید.
@AndroidEntryPoint
یک مؤلفه Hilt جداگانه برای هر کلاس Android در پروژه شما ایجاد می کند. این مؤلفهها میتوانند وابستگیهایی را از کلاسهای والد مربوطه خود دریافت کنند که در سلسله مراتب مؤلفه توضیح داده شده است.
برای به دست آوردن وابستگی از یک جزء، از حاشیه نویسی @Inject
برای انجام تزریق فیلد استفاده کنید:
کاتلین
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { @Inject lateinit var analytics: AnalyticsAdapter ... }
جاوا
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { @Inject AnalyticsAdapter analytics; ... }
کلاس هایی که هیلت تزریق می کند می توانند کلاس های پایه دیگری داشته باشند که از تزریق نیز استفاده می کنند. آن کلاسها اگر انتزاعی باشند، به حاشیهنویسی @AndroidEntryPoint
نیاز ندارند.
برای کسب اطلاعات بیشتر در مورد اینکه یک کلاس Android در کدام یک از چرخه حیات بازگشت به تماس تزریق میشود، به طول عمر مؤلفه مراجعه کنید.
اتصالات هیلت را تعریف کنید
برای انجام تزریق فیلد، Hilt باید بداند که چگونه نمونه هایی از وابستگی های لازم را از مؤلفه مربوطه ارائه دهد. یک اتصال شامل اطلاعات لازم برای ارائه نمونه هایی از یک نوع به عنوان وابستگی است.
یکی از راه های ارائه اطلاعات الزام آور به Hilt، تزریق سازنده است. از حاشیه نویسی @Inject
در سازنده یک کلاس استفاده کنید تا به Hilt بگویید چگونه نمونه هایی از آن کلاس را ارائه کند:
کاتلین
class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
جاوا
public class AnalyticsAdapter { private final AnalyticsService service; @Inject AnalyticsAdapter(AnalyticsService service) { this.service = service; } ... }
پارامترهای یک سازنده حاشیه نویسی یک کلاس، وابستگی های آن کلاس هستند. در مثال، AnalyticsAdapter
دارای AnalyticsService
به عنوان یک وابستگی است. بنابراین، Hilt باید نحوه ارائه نمونه های AnalyticsService
را نیز بداند.
ماژول های هیلت
گاهی اوقات نمی توان یک نوع را به صورت سازنده تزریق کرد. این ممکن است به دلایل متعددی اتفاق بیفتد. به عنوان مثال، شما نمی توانید یک رابط را تزریق کنید. شما همچنین نمی توانید نوعی را که متعلق به شما نیست، مانند کلاسی از یک کتابخانه خارجی، تزریق کنید. در این موارد، می توانید با استفاده از ماژول های Hilt اطلاعات الزام آور را در اختیار Hilt قرار دهید.
ماژول Hilt کلاسی است که با @Module
حاشیه نویسی می شود. مانند یک ماژول Dagger ، به Hilt اطلاع می دهد که چگونه نمونه هایی از انواع خاص را ارائه دهد. برخلاف ماژولهای Dagger، باید ماژولهای Hilt را با @InstallIn
حاشیهنویسی کنید تا به Hilt بگویید هر ماژول در کدام کلاس Android استفاده یا نصب میشود.
وابستگیهایی که در ماژولهای Hilt ارائه میکنید در همه مؤلفههای تولید شده مرتبط با کلاس Android که در آن ماژول Hilt را نصب میکنید، موجود است.
نمونه های رابط را با @Binds تزریق کنید
مثال AnalyticsService
را در نظر بگیرید. اگر AnalyticsService
یک رابط است، نمی توانید آن را تزریق کنید. در عوض، با ایجاد یک تابع انتزاعی مشروح شده با @Binds
در داخل یک ماژول Hilt، اطلاعات اتصال را به 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 }
جاوا
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
در تمام فعالیتهای برنامه در دسترس هستند.
نمونه ها را با @Provides تزریق کنید
رابطها تنها موردی نیستند که نمیتوانید یک نوع را تزریق کنید. تزریق سازنده نیز ممکن نیست اگر شما مالک کلاس نباشید زیرا از یک کتابخانه خارجی (کلاس هایی مانند Retrofit ، OkHttpClient
، یا پایگاه داده اتاق )، یا اگر نمونه هایی باید با الگوی سازنده ایجاد شوند، امکان پذیر نیست.
مثال قبلی را در نظر بگیرید. اگر مستقیماً مالک کلاس 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) } }
جاوا
@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
استفاده میکنید، تعریف کنید:
کاتلین
@Qualifier @Retention(AnnotationRetention.BINARY) annotation class AuthInterceptorOkHttpClient @Qualifier @Retention(AnnotationRetention.BINARY) annotation class OtherInterceptorOkHttpClient
جاوا
@Qualifier @Retention(RetentionPolicy.RUNTIME) private @interface AuthInterceptorOkHttpClient {} @Qualifier @Retention(RetentionPolicy.RUNTIME) private @interface 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() } }
جاوا
@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(); } }
شما می توانید نوع خاصی را که نیاز دارید با حاشیه نویسی فیلد یا پارامتر با واجد شرایط مربوطه تزریق کنید:
کاتلین
// 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 }
جاوا
// 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 برخی از واجد شرایط از پیش تعریف شده را ارائه می دهد. برای مثال، از آنجایی که ممکن است به کلاس Context
از برنامه یا اکتیویتی نیاز داشته باشید، Hilt واجد شرایط @ApplicationContext
و @ActivityContext
را ارائه می دهد.
فرض کنید کلاس AnalyticsAdapter
از مثال به زمینه فعالیت نیاز دارد. کد زیر نحوه ارائه زمینه فعالیت به AnalyticsAdapter
را نشان می دهد:
کاتلین
class AnalyticsAdapter @Inject constructor( @ActivityContext private val context: Context, private val service: AnalyticsService ) { ... }
جاوا
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 که میتوانید در آن تزریق فیلد انجام دهید، یک مؤلفه Hilt مرتبط وجود دارد که میتوانید در حاشیهنویسی @InstallIn
به آن مراجعه کنید. هر جزء Hilt وظیفه تزریق اتصالات خود را به کلاس Android مربوطه دارد.
مثال های قبلی استفاده از ActivityComponent
را در ماژول های Hilt نشان دادند.
Hilt اجزای زیر را ارائه می دهد:
جزء هیلت | انژکتور برای |
---|---|
SingletonComponent | Application |
ActivityRetainedComponent | N/A |
ViewModelComponent | ViewModel |
ActivityComponent | Activity |
FragmentComponent | Fragment |
ViewComponent | View |
ViewWithFragmentComponent | View مشروح شده با @WithFragmentBindings |
ServiceComponent | Service |
طول عمر قطعات
Hilt به طور خودکار نمونه هایی از کلاس های مؤلفه تولید شده را به دنبال چرخه عمر کلاس های Android مربوطه ایجاد و از بین می برد.
جزء تولید شده | ایجاد شده در | در |
---|---|---|
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 همچنین اجازه می دهد تا یک اتصال به یک جزء خاص محدود شود. Hilt فقط یک بار در هر نمونه از مؤلفهای ایجاد میکند که باند به آن محدوده میشود، و همه درخواستها برای آن صحافی نمونه مشابهی دارند.
جدول زیر حاشیه نویسی محدوده برای هر جزء تولید شده را فهرست می کند:
کلاس اندروید | جزء تولید شده | دامنه |
---|---|---|
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 |
در مثال، اگر با استفاده از @ActivityScoped
، AnalyticsAdapter
به ActivityComponent
محدود کنید، Hilt همان نمونه AnalyticsAdapter
را در طول عمر فعالیت مربوطه ارائه میکند:
کاتلین
@ActivityScoped class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
جاوا
@ActivityScoped public class AnalyticsAdapter { private final AnalyticsService service; @Inject AnalyticsAdapter(AnalyticsService service) { this.service = service; } ... }
فرض کنید AnalyticsService
یک حالت داخلی دارد که نیاز دارد هر بار از همان نمونه استفاده شود—نه تنها در ExampleActivity
، بلکه در هر نقطه از برنامه. در این مورد، مناسب است که AnalyticsService
به SingletonComponent
اختصاص دهیم. نتیجه این است که هر زمان که مؤلفه نیاز به ارائه نمونه ای از AnalyticsService
داشته باشد، هر بار همان نمونه را ارائه می دهد.
مثال زیر نشان می دهد که چگونه یک اتصال به یک جزء در یک ماژول Hilt را محدود کنید. محدوده یک binding باید با محدوده مؤلفه ای که در آن نصب شده است مطابقت داشته باشد، بنابراین در این مثال باید AnalyticsService
به جای ActivityComponent
در SingletonComponent
نصب کنید:
کاتلین
// 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) } }
جاوا
// 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، به Scoping در Android و Hilt مراجعه کنید.
سلسله مراتب اجزا
نصب یک ماژول در یک کامپوننت به پیوندهای آن اجازه می دهد تا به عنوان وابستگی به سایر اتصالات در آن مؤلفه یا در هر مؤلفه فرزند زیر آن در سلسله مراتب مؤلفه دسترسی داشته باشید:
اتصالات پیش فرض مؤلفه
هر جزء Hilt دارای مجموعه ای از اتصالات پیش فرض است که Hilt می تواند به عنوان وابستگی به پیوندهای سفارشی شما تزریق کند. توجه داشته باشید که این اتصالات مربوط به فعالیت عمومی و انواع قطعه است و نه به زیر کلاس خاصی. این به این دلیل است که Hilt از یک تعریف جزء فعالیت واحد برای تزریق همه فعالیت ها استفاده می کند. هر فعالیت نمونه متفاوتی از این مؤلفه دارد.
کامپوننت اندروید | صحافی های پیش فرض |
---|---|
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
در دسترس است. به عنوان مثال:
کاتلین
class AnalyticsServiceImpl @Inject constructor( @ApplicationContext context: Context ) : AnalyticsService { ... } // The Application binding is available without qualifiers. class AnalyticsServiceImpl @Inject constructor( application: Application ) : AnalyticsService { ... }
جاوا
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
در دسترس است. به عنوان مثال:
کاتلین
class AnalyticsAdapter @Inject constructor( @ActivityContext context: Context ) { ... } // The Activity binding is available without qualifiers. class AnalyticsAdapter @Inject constructor( activity: FragmentActivity ) { ... }
جاوا
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 از رایج ترین کلاس های اندروید پشتیبانی می کند. با این حال، ممکن است لازم باشد در کلاس هایی که Hilt پشتیبانی نمی کند، تزریق فیلد انجام دهید.
در این موارد، می توانید یک نقطه ورودی با استفاده از حاشیه نویسی @EntryPoint
ایجاد کنید. نقطه ورود مرز بین کدی است که توسط Hilt مدیریت می شود و کدی که مدیریت نمی شود. این نقطه ای است که ابتدا کد وارد نمودار اشیایی می شود که Hilt مدیریت می کند. نقاط ورودی به Hilt اجازه می دهد تا از کدهایی استفاده کند که Hilt قادر به ارائه وابستگی ها در نمودار وابستگی نیست.
به عنوان مثال، Hilt مستقیماً از ارائه دهندگان محتوا پشتیبانی نمی کند. اگر میخواهید یک ارائهدهنده محتوا از Hilt برای دریافت برخی وابستگیها استفاده کند، باید رابطی را تعریف کنید که با @EntryPoint
برای هر نوع پیوندی که میخواهید مشروح شده باشد و شامل واجد شرایط باشد. سپس @InstallIn
را اضافه کنید تا کامپوننتی را که در آن نقطه ورودی نصب شود به صورت زیر مشخص کنید:
کاتلین
class ExampleContentProvider : ContentProvider() { @EntryPoint @InstallIn(SingletonComponent::class) interface ExampleContentProviderEntryPoint { fun analyticsService(): AnalyticsService } ... }
جاوا
public class ExampleContentProvider extends ContentProvider { @EntryPoint @InstallIn(SingletonComponent.class) interface ExampleContentProviderEntryPoint { public 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() ... } }
جاوا
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
استفاده میکردید.
هیلت و خنجر
Hilt در بالای کتابخانه تزریق وابستگی Dagger ساخته شده است، که یک راه استاندارد برای گنجاندن Dagger در یک برنامه اندروید ارائه می دهد.
با توجه به داگر، اهداف هیلت به شرح زیر است:
- برای ساده سازی زیرساخت های مرتبط با Dagger برای برنامه های اندروید.
- برای ایجاد یک مجموعه استاندارد از مؤلفهها و دامنهها برای سهولت راهاندازی، خوانایی و اشتراکگذاری کد بین برنامهها.
- برای ارائه یک راه آسان برای ارائه اتصالات مختلف به انواع مختلف ساخت، مانند آزمایش، اشکال زدایی یا انتشار.
از آنجایی که سیستم عامل اندروید بسیاری از کلاس های فریمورک خود را به نمایش می گذارد، استفاده از Dagger در یک برنامه اندرویدی نیازمند نوشتن مقدار قابل توجهی از دیگ بخار است. Hilt کد دیگ بخار را که در استفاده از Dagger در یک برنامه اندرویدی دخیل است، کاهش می دهد. Hilt به طور خودکار موارد زیر را تولید و ارائه می کند:
- مؤلفههایی برای ادغام کلاسهای فریمورک اندروید با Dagger که در غیر این صورت باید با دست ایجاد کنید.
- حاشیه نویسی دامنه برای استفاده با مؤلفه هایی که Hilt به طور خودکار تولید می کند.
- پیوندهای از پیش تعریف شده برای نمایش کلاس های Android مانند
Application
یاActivity
. - واجد شرایط از پیش تعریف شده برای نشان دادن
@ApplicationContext
و@ActivityContext
.
کد Dagger و Hilt می توانند در یک پایگاه کد وجود داشته باشند. با این حال، در بیشتر موارد بهتر است از Hilt برای مدیریت تمام استفاده خود از Dagger در اندروید استفاده کنید. برای انتقال پروژهای که از Dagger به Hilt استفاده میکند، به راهنمای انتقال و انتقال برنامه Dagger به Hilt codelab مراجعه کنید.
منابع اضافی
برای کسب اطلاعات بیشتر در مورد Hilt، به منابع اضافی زیر مراجعه کنید.
نمونه ها
Codelabs
وبلاگ ها
- تزریق وابستگی در اندروید با Hilt
- Scoping در اندروید و Hilt
- افزودن اجزا به سلسله مراتب Hilt
- انتقال برنامه Google I/O به Hilt