নেভিগেশন কোড মডিউলারাইজ করুন

এই পৃষ্ঠাটি আপনার নেভিগেশন কোডকে মডিউলারাইজ করার জন্য একটি নির্দেশিকা। এটি অ্যাপ মডিউলারাইজেশনের সাধারণ নির্দেশিকার পরিপূরক হিসেবে কাজ করার উদ্দেশ্যে তৈরি।

সংক্ষিপ্ত বিবরণ

আপনার নেভিগেশন কোডকে মডিউলারাইজ করা হলো সম্পর্কিত নেভিগেশন কী এবং সেগুলোর প্রতিনিধিত্বকারী বিষয়বস্তুকে আলাদা আলাদা মডিউলে বিভক্ত করার প্রক্রিয়া। এটি দায়িত্বের একটি সুস্পষ্ট বিভাজন নিশ্চিত করে এবং আপনাকে আপনার অ্যাপের বিভিন্ন ফিচারের মধ্যে নেভিগেট করতে সাহায্য করে।

আপনার নেভিগেশন কোডকে মডিউলারাইজ করতে, নিম্নলিখিতগুলি করুন:

  • আপনার অ্যাপের প্রতিটি ফিচারের জন্য api এবং impl দুটি সাবমডিউল তৈরি করুন।
  • প্রতিটি ফিচারের নেভিগেশন কীগুলো তার api মডিউলে রাখুন।
  • প্রতিটি ফিচারের জন্য entryProviders এবং নেভিগেবল কন্টেন্ট সংশ্লিষ্ট impl মডিউলে রাখুন।
  • আপনার প্রধান অ্যাপ মডিউলগুলিতে entryProviders সরবরাহ করুন, সরাসরি অথবা ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করে।

বৈশিষ্ট্যগুলিকে এপিআই এবং বাস্তবায়ন উপ-মডিউলে বিভক্ত করুন

আপনার অ্যাপের প্রতিটি ফিচারের জন্য api এবং impl (যা ‘ইমপ্লিমেন্টেশন’-এর সংক্ষিপ্ত রূপ) নামে দুটি সাবমডিউল তৈরি করুন। ন্যাভিগেশন কোড কোথায় রাখবেন তা নির্ধারণ করতে নিচের সারণিটি ব্যবহার করুন।

মডিউলের নাম

ধারণ করে

api

নেভিগেশন কী

impl

সেই ফিচারের জন্য বিষয়বস্তু, যার মধ্যে NavEntry এবং entryProvider এর সংজ্ঞা অন্তর্ভুক্ত। আরও দেখুন ‘resolve keys to content’

এই পদ্ধতিটি একটি ফিচারকে অন্য একটি ফিচারে নেভিগেট করার সুযোগ দেয়, যেখানে এর impl মডিউলে থাকা কন্টেন্ট, অন্য একটি মডিউলের api মডিউলে থাকা নেভিগেশন কী-গুলোর উপর নির্ভরশীল থাকে।

ফিচার মডিউল নির্ভরতা ডায়াগ্রাম, যা দেখাচ্ছে কিভাবে `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 ব্যবহার করে, MainActivity এর মালিকানাধীন একটি Set এর মধ্যে এন্ট্রি বিল্ডারগুলিকে ইনজেক্ট করে। এরপর এগুলিকে 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 মাল্টিবাইন্ডিং-এ তার নিজস্ব ম্যাচিং উপাদান যোগ করতে পারে:

বৈশিষ্ট্য মডিউল

তারপর, আপনার মূল অ্যাপ মডিউলে, যেমন আপনার MainActivity তে, আপনি ম্যাচারগুলোর সেট ইনজেক্ট করতে পারেন এবং আগত রিকোয়েস্টগুলো ম্যাচ করার জন্য সেগুলো ব্যবহার করতে পারেন:

অ্যাপ মডিউল

ডিপ লিঙ্কের সংজ্ঞা ও পরিচালনা সম্পর্কে আরও তথ্যের জন্য, ‘ডিপ লিঙ্ক সমর্থন’ দেখুন।

সম্পদ

ন্যাভিগেশন ৩ কোডকে কীভাবে মডিউলারাইজ করতে হয়, তার কোড নমুনার জন্য দেখুন: