এই পৃষ্ঠাটি আপনার নেভিগেশন কোড মডিউলারাইজ করার জন্য একটি গাইড। এটি সাধারণ অ্যাপ মডিউলারাইজেশন সংক্রান্ত নির্দেশিকার পরিপূরক হিসেবে কাজ করে।
এক নজরে
মডিউলারাইজ করা হল নেভিগেশন কোডকে আলাদা আলাদা মডিউলে ভাগ করার প্রক্রিয়া। এর মধ্যে রয়েছে সম্পর্কিত নেভিগেশন কী এবং সেগুলি যে কন্টেন্টকে প্রতিনিধিত্ব করে। এটি দায়িত্বের স্পষ্ট বিভাজন প্রদান করে এবং আপনার অ্যাপের বিভিন্ন ফিচারের মধ্যে নেভিগেট করতে দেয়।
আপনার নেভিগেশন কোড মডিউলারাইজ করতে, নিম্নলিখিত কাজগুলি করুন:
- আপনার অ্যাপের প্রতিটি ফিচারের জন্য দুটি করে সাবমডিউল তৈরি করুন:
apiওimpl - প্রতিটি ফিচারের জন্য নেভিগেশন কী তার
apiমডিউলে রাখুন - প্রতিটি ফিচারের জন্য
entryProvidersও নেভিগেট করা যায় এমন কন্টেন্ট সংশ্লিষ্টimplমডিউলে রাখুন - আপনার মূল অ্যাপ মডিউলে
entryProvidersপ্রদান করুন, সরাসরি অথবা ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে
API ও প্রয়োগ সংক্রান্ত সাবমডিউলে আলাদা আলাদা ফিচার
আপনার অ্যাপের প্রতিটি ফিচারের জন্য, api ও impl নামের দুটি সাবমডিউল তৈরি করুন
("ইমপ্লিমেন্টেশন"-এর সংক্ষিপ্ত রূপ)। নেভিগেশন কোড কোথায় প্লেস করবেন তা ঠিক করতে
নিচের টেবিল ব্যবহার করুন।
মডিউলের নাম |
এর মধ্যে আছে |
|
|
|
সেই ফিচারের কন্টেন্ট, যার মধ্যে
|
এই পদ্ধতিতে, একটি ফিচারের কন্টেন্ট, যা সেটির impl মডিউলে থাকে, তা অন্য মডিউলের নেভিগেশন কীয়ের উপর নির্ভর করে।
এই মডিউলটি আবার সেই মডিউলের api মডিউলে থাকে।
এক্সটেনশন ফাংশন ব্যবহার করে নেভিগেশন এন্ট্রি আলাদা করা
নেভিগেশন ৩-এ, নেভিগেশন এন্ট্রি ব্যবহার করে নেভিগেট করা যায় এমন কন্টেন্টকে সংজ্ঞায়িত করা হয়। এইসব এন্ট্রিকে আলাদা আলাদা মডিউলে
আলাদা করতে, EntryProviderScope-এ এক্সটেনশন ফাংশন তৈরি করুন
এবং সেই ফিচারের জন্য impl মডিউলে সেগুলি সরিয়ে দিন।
এগুলিকে এন্ট্রি বিল্ডার বলা হয়।
নিচের কোডের উদাহরণে একটি এন্ট্রি বিল্ডার দেখানো হয়েছে যা দুটি নেভিগেশন এন্ট্রি তৈরি করে।
// import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey fun EntryProviderScope<NavKey>.featureAEntryBuilder() { entry<KeyA> { ContentRed("Screen A") { // Content for screen A } } entry<KeyA2> { ContentGreen("Screen A2") { // Content for screen A2 } } }
আপনার মূল অ্যাপ মডিউলে
entryProvider ডিফাইন করার সময় entryProvider DSL ব্যবহার করে সেই ফাংশন কল করুন।
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
মূল অ্যাপে এন্ট্রি যোগ করতে ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করা
আগের কোড উদাহরণে, প্রতিটি এন্ট্রি বিল্ডারকে entryProvider DSL ব্যবহার করে
মূল অ্যাপ সরাসরি কল করে। আপনার অ্যাপে অনেক স্ক্রিন বা
ফিচার মডিউল থাকলে, এই প্যাটার্নটি ভালোভাবে স্কেল নাও করতে পারে।
এটি সমাধান করতে, প্রতিটি ফিচার মডিউলকে ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে অ্যাপের অ্যাক্টিভিটিতে তার এন্ট্রি বিল্ডার কন্ট্রিবিউট করতে হবে।
যেমন, নিম্নলিখিত কোডটি Dagger মাল্টিবাইন্ডিং ব্যবহার করে,
বিশেষ করে @IntoSet, Set-এর মালিকানাধীন
MainActivity-এ এন্ট্রি বিল্ডার ইনজেক্ট করতে। এগুলিকে entryProvider-এর মধ্যে ইটারেটিভভাবে কল করা হয়,
যার ফলে অসংখ্য এন্ট্রি বিল্ডার ফাংশনকে আলাদা করে কল করার প্রয়োজন হয় না।
ফিচার মডিউল
// import dagger.Module // import dagger.Provides // import dagger.hilt.InstallIn // import dagger.hilt.android.components.ActivityRetainedComponent // import dagger.multibindings.IntoSet @Module @InstallIn(ActivityRetainedComponent::class) object FeatureAModule { @IntoSet @Provides fun provideFeatureAEntryBuilder() : EntryProviderScope<NavKey>.() -> Unit = { featureAEntryBuilder() } }
অ্যাপ মডিউল
// import android.os.Bundle // import androidx.activity.ComponentActivity // import androidx.activity.compose.setContent // import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey // import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay // import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var entryBuilders: Set<@JvmSuppressWildcards EntryProviderScope<NavKey>.() -> Unit> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NavDisplay( entryProvider = entryProvider { entryBuilders.forEach { builder -> this.builder() } }, // ... ) } } }
আপনার নেভিগেশন এন্ট্রিকে যদি নেভিগেট করতে হয়—যেমন, সেটিতে এমন UI এলিমেন্ট আছে যা নতুন স্ক্রিনে নেভিগেট করে—তাহলে প্রতিটি বিল্ডার ফাংশনে অ্যাপের নেভিগেশন স্টেট পরিবর্তন করতে পারে এমন একটি অবজেক্ট ইনজেক্ট করুন।
ডিপ লিঙ্ক ম্যাচ করা মডিউলারাইজ করা
আপনার অ্যাপে ডিপ লিঙ্ক কাজ করলে এবং সেটি মডিউলারাইজ করা হলে, প্রতিটি ফিচার মডিউলকে
সেটির মালিকানাধীন গন্তব্যের জন্য DeepLinkMatcher ইনস্ট্যান্সকে ডিফাইন করতে হবে।
আপনার অ্যাপ জুড়ে সব ম্যাচিং একত্রিত করতে, আপনি
ডিপেন্ডেন্সি ইনজেকশন মাল্টিবাইন্ডিং ব্যবহার করতে পারেন। যেমন, প্রতিটি ফিচার মডিউল
ড্যাগারের @IntoSet মাল্টিবাইন্ডিংয়ে নিজের ম্যাচ করা কন্ট্রিবিউট করতে পারে:
ফিচার মডিউল
@Module @InstallIn(ActivityRetainedComponent::class) object FeatureADeepLinkModule { @IntoSet @Provides fun provideUserMatcher(): DeepLinkMatcher<*, *> { return UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ) } }
তারপরে, আপনার মূল অ্যাপ মডিউলে, যেমন আপনার MainActivity-এ, আপনি
ম্যাচারদের সেট ইনজেক্ট করতে এবং ইনকামিং অনুরোধ ম্যাচ করার জন্য সেগুলি ব্যবহার করতে পারবেন:
অ্যাপ মডিউল
@AndroidEntryPoint class MainActivityWithDI : ComponentActivity() { @Inject lateinit var deepLinkMatchers: Set<@JvmSuppressWildcards DeepLinkMatcher<*, *>> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val request = DeepLinkRequest(intent = intent) val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } .maxOrNull() val backStack = when (matchResult) { null -> listOf(HomeKey) is BackStackMatchResult<*, *> -> { @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } else -> listOf(matchResult.key) } } }
ডিপ লিঙ্ক নির্ধারণ ও ম্যানেজ করা সম্পর্কে আরও জানতে, ডিপ লিঙ্ক ব্যবহার করা দেখুন।
রিসোর্স
Navigation 3 কোড কীভাবে মডিউলারাইজ করতে হয় তা দেখানোর জন্য কোড স্যাম্পেল পেতে, এগুলি দেখুন:
- Navigation 3 আর্কিটেকচার কোড রেসিপি
- Now in Android অ্যাপ থেকে মডিউলারাইজেশন লার্নিং জার্নি
- Androidify