হিল্ট হ'ল অ্যান্ড্রয়েডের জন্য একটি নির্ভরতা ইনজেকশন লাইব্রেরি যা আপনার প্রকল্পে ম্যানুয়াল নির্ভরতা ইনজেকশন করার বয়লারপ্লেটকে হ্রাস করে। ম্যানুয়াল ডিপেন্ডেন্সি ইনজেকশন করার জন্য আপনাকে প্রতিটি শ্রেণী এবং এর নির্ভরতাগুলিকে হাতে তৈরি করতে হবে এবং নির্ভরতাগুলি পুনরায় ব্যবহার এবং পরিচালনা করতে পাত্রে ব্যবহার করতে হবে।
হিল্ট আপনার প্রজেক্টের প্রতিটি অ্যান্ড্রয়েড ক্লাসের জন্য কন্টেইনার সরবরাহ করে এবং তাদের জীবনচক্র স্বয়ংক্রিয়ভাবে পরিচালনা করে আপনার অ্যাপ্লিকেশনে DI ব্যবহার করার একটি আদর্শ উপায় প্রদান করে। হিল্ট জনপ্রিয় DI লাইব্রেরি Dagger- এর উপরে তৈরি করা হয়েছে কম্পাইল-টাইম শুদ্ধতা, রানটাইম পারফরম্যান্স, স্কেলেবিলিটি এবং অ্যান্ড্রয়েড স্টুডিও সমর্থন যা Dagger প্রদান করে। আরও তথ্যের জন্য, হিল্ট এবং ড্যাগার দেখুন।
এই নির্দেশিকাটি হিল্ট এবং এর তৈরি পাত্রের মৌলিক ধারণাগুলি ব্যাখ্যা করে। এটি হিল্ট ব্যবহার করার জন্য একটি বিদ্যমান অ্যাপকে কীভাবে বুটস্ট্র্যাপ করতে হয় তার একটি প্রদর্শনও অন্তর্ভুক্ত করে।
নির্ভরতা যোগ করা হচ্ছে
প্রথমে, আপনার প্রোজেক্টের রুট build.gradle
ফাইলে hilt-android-gradle-plugin
প্লাগইন যোগ করুন:
গ্রোভি
plugins { ... id 'com.google.dagger.hilt.android' version '2.44' apply false }
কোটলিন
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 }
কোটলিন
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 }
হিল্ট জাভা 8 বৈশিষ্ট্য ব্যবহার করে। আপনার প্রকল্পে Java 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 } }
হিল্ট অ্যাপ্লিকেশন ক্লাস
হিল্ট ব্যবহার করে এমন সব অ্যাপে অবশ্যই @HiltAndroidApp
এর সাথে টীকাযুক্ত একটি Application
ক্লাস থাকতে হবে।
@HiltAndroidApp
হিল্টের কোড জেনারেশন ট্রিগার করে, আপনার অ্যাপ্লিকেশনের জন্য একটি বেস ক্লাস সহ যা অ্যাপ্লিকেশন-স্তরের নির্ভরতা ধারক হিসাবে কাজ করে।
কোটলিন
@HiltAndroidApp class ExampleApplication : Application() { ... }
জাভা
@HiltAndroidApp public class ExampleApplication extends Application { ... }
এই উৎপন্ন হিল্ট উপাদানটি Application
অবজেক্টের জীবনচক্রের সাথে সংযুক্ত থাকে এবং এটির উপর নির্ভরতা প্রদান করে। অতিরিক্তভাবে, এটি অ্যাপটির মূল উপাদান, যার অর্থ অন্যান্য উপাদানগুলি এটি সরবরাহ করে এমন নির্ভরতাগুলি অ্যাক্সেস করতে পারে।
অ্যান্ড্রয়েড ক্লাসে নির্ভরতা ইনজেক্ট করুন
একবার আপনার Application
ক্লাসে হিল্ট সেট আপ হয়ে গেলে এবং একটি অ্যাপ্লিকেশন-স্তরের উপাদান উপলব্ধ হলে, হিল্ট অন্যান্য অ্যান্ড্রয়েড ক্লাসগুলিতে নির্ভরতা প্রদান করতে পারে যেখানে @AndroidEntryPoint
টীকা রয়েছে:
কোটলিন
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { ... }
জাভা
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { ... }
হিল্ট বর্তমানে নিম্নলিখিত অ্যান্ড্রয়েড ক্লাসগুলিকে সমর্থন করে:
-
Application
(@HiltAndroidApp
ব্যবহার করে) -
ViewModel
(@HiltViewModel
ব্যবহার করে) -
Activity
-
Fragment
-
View
-
Service
-
BroadcastReceiver
আপনি যদি @AndroidEntryPoint
এর সাথে একটি অ্যান্ড্রয়েড ক্লাস টীকা করেন, তাহলে আপনাকে অবশ্যই এটির উপর নির্ভরশীল অ্যান্ড্রয়েড ক্লাসগুলিকে টীকা করতে হবে৷ উদাহরণস্বরূপ, যদি আপনি একটি খণ্ডটি টীকা করেন, তাহলে আপনাকে অবশ্যই যে কোনো ক্রিয়াকলাপকে টীকা দিতে হবে যেখানে আপনি সেই খণ্ডটি ব্যবহার করেন।
@AndroidEntryPoint
আপনার প্রজেক্টের প্রতিটি অ্যান্ড্রয়েড ক্লাসের জন্য একটি পৃথক হিল্ট উপাদান তৈরি করে। এই উপাদানগুলি তাদের নিজ নিজ অভিভাবক শ্রেণী থেকে কম্পোনেন্ট শ্রেণিবিন্যাসে বর্ণিত নির্ভরতা পেতে পারে।
একটি উপাদান থেকে নির্ভরতা পেতে, ক্ষেত্র ইনজেকশন সঞ্চালনের জন্য @Inject
টীকাটি ব্যবহার করুন:
কোটলিন
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { @Inject lateinit var analytics: AnalyticsAdapter ... }
জাভা
@AndroidEntryPoint public class ExampleActivity extends AppCompatActivity { @Inject AnalyticsAdapter analytics; ... }
যে ক্লাসগুলি হিল্ট ইনজেকশন দেয় সেগুলির অন্যান্য বেস ক্লাস থাকতে পারে যেগুলি ইনজেকশনও ব্যবহার করে। এই ক্লাসগুলির @AndroidEntryPoint
টীকা প্রয়োজন নেই যদি সেগুলি বিমূর্ত হয়।
কোন Android ক্লাসে লাইফসাইকেল কলব্যাক ইনজেক্ট করা হয় সে সম্পর্কে আরও জানতে, কম্পোনেন্ট লাইফটাইম দেখুন।
হিল্ট বাইন্ডিং সংজ্ঞায়িত করুন
ফিল্ড ইনজেকশন সঞ্চালনের জন্য, হিল্টকে সংশ্লিষ্ট উপাদান থেকে প্রয়োজনীয় নির্ভরতার উদাহরণগুলি কীভাবে সরবরাহ করতে হয় তা জানতে হবে। একটি বাইন্ডিং একটি নির্ভরতা হিসাবে একটি ধরনের দৃষ্টান্ত প্রদান করার জন্য প্রয়োজনীয় তথ্য ধারণ করে।
হিল্টে আবদ্ধ তথ্য প্রদানের একটি উপায় হল কনস্ট্রাক্টর ইনজেকশন । একটি ক্লাসের কনস্ট্রাক্টরের উপর @Inject
টীকাটি ব্যবহার করুন হিল্টকে কীভাবে সেই ক্লাসের দৃষ্টান্ত প্রদান করতে হয় তা জানাতে:
কোটলিন
class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... }
জাভা
public class AnalyticsAdapter { private final AnalyticsService service; @Inject AnalyticsAdapter(AnalyticsService service) { this.service = service; } ... }
একটি ক্লাসের টীকাযুক্ত কনস্ট্রাক্টরের পরামিতি হল সেই শ্রেণীর নির্ভরতা। উদাহরণে, AnalyticsAdapter
একটি নির্ভরতা হিসাবে AnalyticsService
রয়েছে৷ তাই, হিল্টকেও জানতে হবে কিভাবে AnalyticsService
উদাহরণ প্রদান করতে হয়।
হিল্ট মডিউল
কখনও কখনও একটি টাইপ কনস্ট্রাক্টর-ইনজেক্ট করা যায় না। এটি একাধিক কারণে ঘটতে পারে। উদাহরণস্বরূপ, আপনি একটি ইন্টারফেস কনস্ট্রাক্টর-ইনজেক্ট করতে পারবেন না। আপনি এমন একটি টাইপ কনস্ট্রাক্টর-ইনজেক্ট করতে পারবেন না যা আপনার নিজের নয়, যেমন একটি বহিরাগত লাইব্রেরি থেকে একটি ক্লাস। এই ক্ষেত্রে, আপনি Hilt মডিউল ব্যবহার করে বাঁধাই তথ্য সহ Hilt প্রদান করতে পারেন।
একটি হিল্ট মডিউল হল একটি ক্লাস যা @Module
দিয়ে টীকা করা হয়। একটি ড্যাগার মডিউলের মতো, এটি হিল্টকে জানায় যে কীভাবে নির্দিষ্ট ধরণের উদাহরণ প্রদান করতে হয়। Dagger মডিউলের বিপরীতে, আপনাকে হিল্ট মডিউলগুলিকে @InstallIn
এর সাথে টীকা করতে হবে যাতে হিল্টকে বলা যায় যে প্রতিটি মডিউল কোন অ্যান্ড্রয়েড ক্লাসে ব্যবহার বা ইনস্টল করা হবে।
আপনি হিল্ট মডিউলে যে নির্ভরতাগুলি প্রদান করেন সেগুলি সমস্ত জেনারেট হওয়া উপাদানগুলিতে উপলব্ধ যা Android ক্লাসের সাথে যুক্ত যেখানে আপনি হিল্ট মডিউল ইনস্টল করেন৷
@Binds এর সাথে ইন্টারফেস ইনস্ট্যান্স ইনজেক্ট করুন
AnalyticsService
উদাহরণ বিবেচনা করুন. AnalyticsService
যদি একটি ইন্টারফেস হয়, তাহলে আপনি এটি কনস্ট্রাক্টর-ইনজেক্ট করতে পারবেন না। পরিবর্তে, হিল্ট মডিউলের ভিতরে @Binds
এর সাথে টীকাযুক্ত একটি বিমূর্ত ফাংশন তৈরি করে বাইন্ডিং তথ্য সহ Hilt প্রদান করুন।
@Binds
টীকা হিল্টকে বলে যে কোন প্রয়োগটি ব্যবহার করতে হবে যখন এটি একটি ইন্টারফেসের একটি উদাহরণ প্রদান করতে হবে।
টীকাকৃত ফাংশন হিল্টকে নিম্নলিখিত তথ্য সরবরাহ করে:
- ফাংশন রিটার্ন টাইপ হিল্টকে বলে যে ফাংশনটি কোন ইন্টারফেসের উদাহরণ প্রদান করে।
- ফাংশন প্যারামিটার হিল্টকে বলে যে কোন বাস্তবায়ন প্রদান করতে হবে।
কোটলিন
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 ); }
হিল্ট মডিউল AnalyticsModule
@InstallIn(ActivityComponent.class)
দিয়ে টীকা করা হয়েছে কারণ আপনি চান যে হিল্ট সেই নির্ভরতা ExampleActivity
তে ইনজেক্ট করুক। এই টীকাটির অর্থ হল AnalyticsModule
সমস্ত নির্ভরতা অ্যাপের সমস্ত কার্যকলাপে উপলব্ধ।
@Provides দিয়ে ইনজেকশন ইনজেকশন করুন
ইন্টারফেসগুলি একমাত্র ক্ষেত্রে নয় যেখানে আপনি একটি টাইপ কনস্ট্রাক্টর-ইনজেক্ট করতে পারবেন না। আপনি যদি ক্লাসের মালিক না হন তবে কনস্ট্রাক্টর ইনজেকশনও সম্ভব নয় কারণ এটি একটি বাহ্যিক লাইব্রেরি থেকে আসে (শ্রেণীগুলি যেমন Retrofit , OkHttpClient
, বা রুম ডেটাবেস ), অথবা যদি উদাহরণগুলি অবশ্যই বিল্ডার প্যাটার্নের সাথে তৈরি করা উচিত।
আগের উদাহরণ বিবেচনা করুন। আপনি যদি সরাসরি AnalyticsService
ক্লাসের মালিক না হন, তাহলে আপনি হিল্ট মডিউলের ভিতরে একটি ফাংশন তৈরি করে এবং @Provides
এর সাথে সেই ফাংশনটি টীকা দিয়ে কীভাবে এই ধরনের উদাহরণ প্রদান করবেন তা হিল্টকে বলতে পারেন।
টীকাকৃত ফাংশন হিল্টে নিম্নলিখিত তথ্য সরবরাহ করে:
- ফাংশন রিটার্ন টাইপ হিল্টকে বলে যে ফাংশনটি কোন ধরনের উদাহরণ প্রদান করে।
- ফাংশন প্যারামিটারগুলি হিল্টকে সংশ্লিষ্ট প্রকারের নির্ভরতা বলে।
- ফাংশন বডি হিল্টকে বলে কিভাবে সংশ্লিষ্ট ধরনের একটি উদাহরণ প্রদান করতে হয়। হিল্ট প্রতিবার ফাংশন বডিকে সেই ধরনের একটি উদাহরণ প্রদান করার প্রয়োজনে কার্যকর করে।
কোটলিন
@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); } }
একই ধরনের জন্য একাধিক বাইন্ডিং প্রদান করুন
যে ক্ষেত্রে আপনার নির্ভরতা হিসাবে একই ধরণের বিভিন্ন বাস্তবায়ন প্রদানের জন্য হিল্টের প্রয়োজন, আপনাকে অবশ্যই একাধিক বাইন্ডিং সহ হিল্ট প্রদান করতে হবে। আপনি কোয়ালিফায়ারগুলির সাথে একই ধরণের জন্য একাধিক বাইন্ডিং সংজ্ঞায়িত করতে পারেন।
একটি কোয়ালিফায়ার হল একটি টীকা যা আপনি একটি টাইপের জন্য একটি নির্দিষ্ট বাইন্ডিং সনাক্ত করতে ব্যবহার করেন যখন সেই টাইপের একাধিক বাইন্ডিং সংজ্ঞায়িত থাকে।
উদাহরণ বিবেচনা করুন। আপনার যদি AnalyticsService
কল ইন্টারসেপ্ট করতে হয়, তাহলে আপনি ইন্টারসেপ্টর সহ একটি OkHttpClient
অবজেক্ট ব্যবহার করতে পারেন। অন্যান্য পরিষেবাগুলির জন্য, আপনাকে অন্যভাবে কলগুলিকে বাধা দিতে হতে পারে৷ সেই ক্ষেত্রে, আপনাকে হিল্টকে বলতে হবে কিভাবে 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 {}
তারপরে, হিল্টকে জানতে হবে কিভাবে প্রতিটি কোয়ালিফায়ারের সাথে সঙ্গতিপূর্ণ ধরনের একটি উদাহরণ প্রদান করতে হয়। এই ক্ষেত্রে, আপনি @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; ... }
একটি সর্বোত্তম অনুশীলন হিসাবে, আপনি যদি একটি প্রকারে একটি যোগ্যতা যোগ করেন, সেই নির্ভরতা প্রদানের সমস্ত সম্ভাব্য উপায়ে যোগ্যতা যোগ করুন। একটি কোয়ালিফায়ার ছাড়া বেস বা সাধারণ বাস্তবায়ন ত্যাগ করা ত্রুটি-প্রবণ এবং এর ফলে হিল্ট ভুল নির্ভরতা ইনজেকশন করতে পারে।
হিল্টে পূর্বনির্ধারিত কোয়ালিফায়ার
হিল্ট কিছু পূর্বনির্ধারিত কোয়ালিফায়ার প্রদান করে। উদাহরণস্বরূপ, অ্যাপ্লিকেশন বা কার্যকলাপ থেকে আপনার Context
ক্লাসের প্রয়োজন হতে পারে, হিল্ট @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; } }
হিল্টে উপলব্ধ অন্যান্য পূর্বনির্ধারিত বাইন্ডিংয়ের জন্য, কম্পোনেন্ট ডিফল্ট বাইন্ডিং দেখুন।
অ্যান্ড্রয়েড ক্লাসের জন্য তৈরি উপাদান
প্রতিটি অ্যান্ড্রয়েড ক্লাসের জন্য যেখানে আপনি ফিল্ড ইনজেকশন করতে পারেন, সেখানে একটি সংশ্লিষ্ট হিল্ট উপাদান রয়েছে যা আপনি @InstallIn
টীকাতে উল্লেখ করতে পারেন। প্রতিটি হিল্ট উপাদান সংশ্লিষ্ট অ্যান্ড্রয়েড ক্লাসে এর বাইন্ডিং ইনজেকশন করার জন্য দায়ী।
পূর্ববর্তী উদাহরণগুলি হিল্ট মডিউলগুলিতে ActivityComponent
ব্যবহার প্রদর্শন করেছে।
হিল্ট নিম্নলিখিত উপাদানগুলি প্রদান করে:
হিল্ট উপাদান | জন্য ইনজেক্টর |
---|---|
SingletonComponent | Application |
ActivityRetainedComponent | N/A |
ViewModelComponent | ViewModel |
ActivityComponent | Activity |
FragmentComponent | Fragment |
ViewComponent | View |
ViewWithFragmentComponent | @WithFragmentBindings এর সাথে টীকাযুক্ত View |
ServiceComponent | Service |
উপাদান জীবনকাল
হিল্ট স্বয়ংক্রিয়ভাবে সংশ্লিষ্ট অ্যান্ড্রয়েড ক্লাসের জীবনচক্র অনুসরণ করে জেনারেট হওয়া কম্পোনেন্ট ক্লাসের উদাহরণ তৈরি করে এবং ধ্বংস করে।
উত্পন্ন উপাদান | এ তৈরি করা হয়েছে | এ ধ্বংস করা হয় |
---|---|---|
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() |
উপাদান স্কোপ
ডিফল্টরূপে, হিল্টের সমস্ত বাঁধাই অস্কোপড । এর মানে হল যে প্রতিবার আপনার অ্যাপ বাইন্ডিংয়ের অনুরোধ করে, হিল্ট প্রয়োজনীয় ধরনের একটি নতুন উদাহরণ তৈরি করে।
উদাহরণে, প্রতিবার হিল্ট AnalyticsAdapter
প্রদান করে অন্য ধরণের উপর নির্ভরতা হিসাবে বা ফিল্ড ইনজেকশনের মাধ্যমে (যেমন ExampleActivity
হিসাবে), Hilt AnalyticsAdapter
এর একটি নতুন উদাহরণ প্রদান করে।
যাইহোক, হিল্ট একটি নির্দিষ্ট উপাদানের জন্য একটি বাঁধাইকে স্কোপ করার অনুমতি দেয়। বাইন্ডিং যে কম্পোনেন্টে স্কোপ করা হয়েছে তার জন্য হিল্ট শুধুমাত্র একবার একটি স্কোপড বাইন্ডিং তৈরি করে এবং সেই বাইন্ডিংয়ের জন্য সমস্ত অনুরোধ একই উদাহরণ ভাগ করে।
নীচের সারণী প্রতিটি উত্পন্ন উপাদানের জন্য সুযোগ টীকা তালিকাভুক্ত করে:
অ্যান্ড্রয়েড ক্লাস | উত্পন্ন উপাদান | ব্যাপ্তি |
---|---|---|
Application | SingletonComponent | @Singleton |
Activity | ActivityRetainedComponent | @ActivityRetainedScoped |
ViewModel | ViewModelComponent | @ViewModelScoped |
Activity | ActivityComponent | @ActivityScoped |
Fragment | FragmentComponent | @FragmentScoped |
View | ViewComponent | @ViewScoped |
@WithFragmentBindings এর সাথে টীকাযুক্ত View | ViewWithFragmentComponent | @ViewScoped |
Service | ServiceComponent | @ServiceScoped |
উদাহরণে, যদি আপনি @ActivityScoped
ব্যবহার করে ActivityComponent
AnalyticsAdapter
স্কোপ করেন, হিল্ট সংশ্লিষ্ট অ্যাক্টিভিটির সারাজীবনে 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
তে নয়, অ্যাপের যেকোনো জায়গায়। এই ক্ষেত্রে, SingletonComponent
এ AnalyticsService
স্কোপ করা উপযুক্ত। ফলাফল হল যে যখনই উপাদানটিকে AnalyticsService
এর একটি উদাহরণ প্রদান করার প্রয়োজন হয়, এটি প্রতিবার একই উদাহরণ প্রদান করে।
নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি হিল্ট মডিউলে একটি উপাদানের সাথে বাঁধাই করার সুযোগ দেওয়া যায়। একটি বাইন্ডিং এর সুযোগ অবশ্যই উপাদানটির সুযোগের সাথে মিলবে যেখানে এটি ইনস্টল করা হয়েছে, তাই এই উদাহরণে আপনাকে ActivityComponent
এর পরিবর্তে SingletonComponent
এ AnalyticsService
ইনস্টল করতে হবে:
কোটলিন
// 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); } }
হিল্ট কম্পোনেন্ট স্কোপ সম্পর্কে আরও জানতে, অ্যান্ড্রয়েড এবং হিল্টে স্কোপিং দেখুন।
উপাদান অনুক্রম
একটি কম্পোনেন্টে একটি মডিউল ইনস্টল করলে সেটির বাইন্ডিংগুলিকে সেই কম্পোনেন্টের অন্যান্য বাইন্ডিংয়ের নির্ভরতা হিসাবে অ্যাক্সেস করা যায় বা কম্পোনেন্ট হায়ারার্কিতে এটির নীচে থাকা যেকোনো চাইল্ড কম্পোনেন্টে:
কম্পোনেন্ট ডিফল্ট বাইন্ডিং
প্রতিটি হিল্ট কম্পোনেন্ট ডিফল্ট বাইন্ডিংয়ের একটি সেট সহ আসে যা হিল্ট আপনার নিজস্ব কাস্টম বাইন্ডিংগুলিতে নির্ভরতা হিসাবে ইনজেক্ট করতে পারে। মনে রাখবেন যে এই বাইন্ডিংগুলি সাধারণ কার্যকলাপ এবং খণ্ডের প্রকারের সাথে সামঞ্জস্যপূর্ণ এবং কোন নির্দিষ্ট উপশ্রেণীর সাথে নয়। এর কারণ হল হিল্ট সমস্ত ক্রিয়াকলাপ ইনজেক্ট করার জন্য একটি একক কার্যকলাপ উপাদান সংজ্ঞা ব্যবহার করে। প্রতিটি কার্যকলাপ এই উপাদান একটি ভিন্ন উদাহরণ আছে.
অ্যান্ড্রয়েড উপাদান | ডিফল্ট বাঁধাই |
---|---|
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; } }
হিল্ট দ্বারা সমর্থিত নয় এমন ক্লাসে নির্ভরতা ইনজেক্ট করুন
হিল্ট সবচেয়ে সাধারণ অ্যান্ড্রয়েড ক্লাসগুলির জন্য সমর্থন সহ আসে। যাইহোক, হিল্ট সমর্থন করে না এমন ক্লাসে আপনাকে ফিল্ড ইনজেকশন করতে হতে পারে।
এই ক্ষেত্রে, আপনি @EntryPoint
টীকা ব্যবহার করে একটি এন্ট্রি পয়েন্ট তৈরি করতে পারেন। একটি এন্ট্রি পয়েন্ট হল কোডের মধ্যে সীমানা যা হিল্ট দ্বারা পরিচালিত হয় এবং কোডটি নয়। এটি সেই বিন্দু যেখানে কোড প্রথমে হিল্ট পরিচালনা করে এমন বস্তুর গ্রাফে প্রবেশ করে। এন্ট্রি পয়েন্টগুলি হিল্টকে কোড ব্যবহার করার অনুমতি দেয় যা হিল্ট নির্ভরতা গ্রাফের মধ্যে নির্ভরতা প্রদান করতে পরিচালনা করে না।
উদাহরণস্বরূপ, হিল্ট সরাসরি সামগ্রী প্রদানকারীদের সমর্থন করে না। আপনি যদি চান যে কোনো বিষয়বস্তু প্রদানকারী কিছু নির্ভরতা পেতে হিল্ট ব্যবহার করুক, তাহলে আপনাকে এমন একটি ইন্টারফেস নির্ধারণ করতে হবে যা @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
স্ট্যাটিক পদ্ধতি উভয়ই @EntryPoint
ইন্টারফেসে @InstallIn
টীকাতে Android ক্লাসের সাথে মেলে:
কোটলিন
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
ব্যবহার করবেন।
হিল্ট এবং ড্যাগার
হিল্টটি ড্যাগার নির্ভরতা ইনজেকশন লাইব্রেরির উপরে তৈরি করা হয়েছে, যা একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশনে ড্যাগারকে অন্তর্ভুক্ত করার একটি আদর্শ উপায় প্রদান করে।
ড্যাগারের ক্ষেত্রে, হিল্টের লক্ষ্যগুলি নিম্নরূপ:
- অ্যান্ড্রয়েড অ্যাপের জন্য ড্যাগার-সম্পর্কিত পরিকাঠামো সহজ করতে।
- অ্যাপগুলির মধ্যে সেটআপ, পঠনযোগ্যতা এবং কোড ভাগ করা সহজ করতে উপাদানগুলির একটি মানক সেট এবং সুযোগ তৈরি করতে৷
- টেস্টিং, ডিবাগ বা রিলিজের মতো বিভিন্ন বিল্ড টাইপের বিভিন্ন বাইন্ডিং প্রভিশন করার একটি সহজ উপায় প্রদান করা।
কারণ অ্যান্ড্রয়েড অপারেটিং সিস্টেম তার নিজস্ব অনেকগুলি ফ্রেমওয়ার্ক ক্লাসকে ইনস্ট্যান্টিয়েট করে, একটি অ্যান্ড্রয়েড অ্যাপে ড্যাগার ব্যবহার করার জন্য আপনাকে যথেষ্ট পরিমাণে বয়লারপ্লেট লিখতে হবে। হিল্ট বয়লারপ্লেট কোড হ্রাস করে যা একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশনে ড্যাগার ব্যবহারে জড়িত। হিল্ট স্বয়ংক্রিয়ভাবে তৈরি করে এবং নিম্নলিখিতগুলি সরবরাহ করে:
- ড্যাগারের সাথে অ্যান্ড্রয়েড ফ্রেমওয়ার্ক ক্লাসগুলিকে একীভূত করার জন্য উপাদানগুলি যা আপনাকে অন্যথায় হাতে তৈরি করতে হবে৷
- হিল্ট স্বয়ংক্রিয়ভাবে তৈরি করে এমন উপাদানগুলির সাথে ব্যবহার করার জন্য স্কোপ টীকা ।
-
Application
বাActivity
মতো অ্যান্ড্রয়েড ক্লাসগুলিকে উপস্থাপন করার জন্য পূর্বনির্ধারিত বাইন্ডিং । -
@ApplicationContext
এবং@ActivityContext
প্রতিনিধিত্ব করার জন্য পূর্বনির্ধারিত কোয়ালিফায়ার ।
ড্যাগার এবং হিল্ট কোড একই কোডবেসে সহাবস্থান করতে পারে। যাইহোক, বেশিরভাগ ক্ষেত্রে আপনার Android এ Dagger এর সমস্ত ব্যবহার পরিচালনা করতে Hilt ব্যবহার করা ভাল। হিল্টে ড্যাগার ব্যবহার করে এমন একটি প্রকল্প স্থানান্তর করতে, মাইগ্রেশন গাইড এবং হিল্ট কোডল্যাবে আপনার ড্যাগার অ্যাপ স্থানান্তরিত করা দেখুন।
অতিরিক্ত সম্পদ
হিল্ট সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন।
নমুনা
কোডল্যাব
ব্লগ
- হিল্ট সহ অ্যান্ড্রয়েডে নির্ভরতা ইনজেকশন
- অ্যান্ড্রয়েড এবং হিল্টে স্কোপিং
- হিল্ট অনুক্রমের উপাদান যোগ করা হচ্ছে
- হিল্টে Google I/O অ্যাপ স্থানান্তর করা হচ্ছে