UI রাজ্য উত্পাদন

আধুনিক UIs খুব কমই স্থিতিশীল। ব্যবহারকারী যখন UI এর সাথে ইন্টারঅ্যাক্ট করে বা যখন অ্যাপটিকে নতুন ডেটা প্রদর্শনের প্রয়োজন হয় তখন UI এর অবস্থা পরিবর্তিত হয়।

এই নথিটি UI রাজ্যের উত্পাদন এবং পরিচালনার জন্য নির্দেশিকা নির্ধারণ করে৷ এটির শেষে আপনার উচিত:

  • UI অবস্থা তৈরি করতে আপনার কোন API ব্যবহার করা উচিত তা জানুন। এটি নির্ভর করে আপনার রাজ্যের ধারকদের মধ্যে উপলব্ধ রাষ্ট্রীয় পরিবর্তনের উত্সগুলির প্রকৃতির উপর, একমুখী ডেটা প্রবাহ নীতি অনুসরণ করে।
  • সিস্টেম রিসোর্স সম্পর্কে সচেতন হতে আপনার UI স্টেটের উৎপাদনের সুযোগ কীভাবে করা উচিত তা জানুন।
  • UI দ্বারা ব্যবহারের জন্য আপনার কীভাবে UI অবস্থা প্রকাশ করা উচিত তা জানুন।

মৌলিকভাবে, রাষ্ট্রীয় উৎপাদন হল UI রাজ্যে এই পরিবর্তনগুলির ক্রমবর্ধমান প্রয়োগ। রাষ্ট্র সর্বদা বিদ্যমান, এবং এটি ঘটনার ফলে পরিবর্তিত হয়। ইভেন্ট এবং রাষ্ট্রের মধ্যে পার্থক্যগুলি নীচের সারণীতে সংক্ষিপ্ত করা হয়েছে:

ঘটনা অবস্থা
ক্ষণস্থায়ী, অনির্দেশ্য, এবং একটি সীমাবদ্ধ সময়ের জন্য বিদ্যমান। সর্বদা বিদ্যমান।
রাষ্ট্রীয় উৎপাদনের ইনপুট। রাষ্ট্রীয় উৎপাদনের আউটপুট।
UI বা অন্যান্য উত্সের পণ্য। UI দ্বারা গ্রাস করা হয়।

একটি মহান স্মারক যা উপরোক্ত সংক্ষিপ্ত বিবরণ রাষ্ট্র হয়; ঘটনা ঘটে । নিচের চিত্রটি একটি টাইমলাইনে ঘটনা ঘটলে অবস্থার পরিবর্তনগুলি কল্পনা করতে সাহায্য করে৷ প্রতিটি ইভেন্ট উপযুক্ত রাষ্ট্র ধারক দ্বারা প্রক্রিয়া করা হয় এবং এটি একটি রাষ্ট্র পরিবর্তনের ফলে:

ঘটনা বনাম রাজ্য
চিত্র 1 : ঘটনা রাষ্ট্র পরিবর্তন ঘটায়

ইভেন্টগুলি থেকে আসতে পারে:

  • ব্যবহারকারী : তারা অ্যাপের UI এর সাথে ইন্টারঅ্যাক্ট করে।
  • রাষ্ট্র পরিবর্তনের অন্যান্য উত্স : API যেগুলি UI, ডোমেন, বা স্ন্যাকবার টাইমআউট ইভেন্টের মতো ডেটা স্তরগুলি থেকে অ্যাপ ডেটা উপস্থাপন করে, যথাক্রমে কেস বা সংগ্রহস্থলগুলি ব্যবহার করে৷

UI রাজ্য উত্পাদন পাইপলাইন

অ্যান্ড্রয়েড অ্যাপগুলিতে রাজ্য উত্পাদনকে একটি প্রক্রিয়াকরণ পাইপলাইন হিসাবে বিবেচনা করা যেতে পারে যার মধ্যে রয়েছে:

  • ইনপুট : রাষ্ট্র পরিবর্তনের উত্স. তারা হতে পারে:
    • UI স্তরের স্থানীয়: এগুলি ব্যবহারকারীর ইভেন্ট হতে পারে যেমন কোনও ব্যবহারকারী একটি টাস্ক ম্যানেজমেন্ট অ্যাপে "টু-ডু" এর জন্য একটি শিরোনাম প্রবেশ করান, বা API যেগুলি UI লজিকে অ্যাক্সেস প্রদান করে যা UI অবস্থায় পরিবর্তন আনে৷ উদাহরণস্বরূপ, জেটপ্যাক কম্পোজে DrawerState open পদ্ধতিতে কল করা।
    • UI স্তরের বাহ্যিক: এগুলি ডোমেন বা ডেটা স্তরগুলির উত্স যা UI অবস্থায় পরিবর্তন ঘটায়। উদাহরণ স্বরূপ নিউজ NewsRepository বা অন্যান্য ইভেন্ট থেকে লোড হওয়া শেষ হওয়া খবর।
    • উপরের সবগুলোর মিশ্রণ।
  • স্টেট হোল্ডার : যে প্রকারগুলি রাষ্ট্রীয় পরিবর্তনের উত্সগুলিতে ব্যবসায়িক যুক্তি এবং/অথবা UI যুক্তি প্রয়োগ করে এবং UI অবস্থা তৈরি করতে ব্যবহারকারী ইভেন্টগুলি প্রক্রিয়া করে।
  • আউটপুট : UI স্টেট যা অ্যাপ ব্যবহারকারীদের তাদের প্রয়োজনীয় তথ্য প্রদান করতে রেন্ডার করতে পারে।
রাষ্ট্রীয় উৎপাদন পাইপলাইন
চিত্র 2 : রাষ্ট্রীয় উৎপাদন পাইপলাইন

রাজ্য উত্পাদন API

আপনি যে পাইপলাইনে আছেন তার উপর নির্ভর করে রাষ্ট্রীয় উৎপাদনে দুটি প্রধান API ব্যবহার করা হয়:

পাইপলাইন পর্যায় API
ইনপুট UI জ্যাঙ্ক মুক্ত রাখতে UI থ্রেড থেকে কাজ সম্পাদন করতে আপনার অ্যাসিঙ্ক্রোনাস API ব্যবহার করা উচিত। উদাহরণস্বরূপ, কোটলিনে Coroutines বা Flows এবং RxJava বা জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজে কলব্যাক।
আউটপুট যখন অবস্থার পরিবর্তন হয় তখন UI কে অবৈধ এবং পুনরায় রেন্ডার করতে আপনার পর্যবেক্ষণযোগ্য ডেটা ধারক API ব্যবহার করা উচিত। উদাহরণস্বরূপ, স্টেটফ্লো, কম্পোজ স্টেট বা লাইভডেটা। পর্যবেক্ষণযোগ্য ডেটা হোল্ডাররা গ্যারান্টি দেয় যে UI-এর সবসময় স্ক্রিনে প্রদর্শনের জন্য একটি UI অবস্থা থাকে

দুটির মধ্যে, ইনপুটের জন্য অ্যাসিঙ্ক্রোনাস API-এর পছন্দ আউটপুটের জন্য পর্যবেক্ষণযোগ্য API-এর পছন্দের চেয়ে রাজ্য উত্পাদন পাইপলাইনের প্রকৃতির উপর বেশি প্রভাব ফেলে। এটি কারণ ইনপুটগুলি পাইপলাইনে প্রয়োগ করা যেতে পারে এমন প্রক্রিয়াকরণের ধরণ নির্দেশ করে

রাজ্য উত্পাদন পাইপলাইন সমাবেশ

পরবর্তী বিভাগগুলি বিভিন্ন ইনপুট এবং মেলে এমন আউটপুট APIগুলির জন্য সবচেয়ে উপযুক্ত রাষ্ট্রীয় উত্পাদন কৌশলগুলিকে কভার করে। প্রতিটি রাষ্ট্রীয় উত্পাদন পাইপলাইন ইনপুট এবং আউটপুটগুলির সংমিশ্রণ এবং এটি হওয়া উচিত:

  • লাইফসাইকেল সচেতন : যে ক্ষেত্রে UI দৃশ্যমান বা সক্রিয় নয়, রাজ্য উত্পাদন পাইপলাইন স্পষ্টভাবে প্রয়োজন না হলে কোনও সংস্থান গ্রহণ করা উচিত নয়।
  • ব্যবহার করা সহজ : UI সহজেই উত্পাদিত UI অবস্থা রেন্ডার করতে সক্ষম হওয়া উচিত। স্টেট প্রোডাকশন পাইপলাইনের আউটপুটের জন্য বিবেচনা বিভিন্ন ভিউ এপিআই যেমন ভিউ সিস্টেম বা জেটপ্যাক কম্পোজ জুড়ে পরিবর্তিত হবে।

রাষ্ট্রীয় উৎপাদন পাইপলাইনে ইনপুট

একটি রাষ্ট্রীয় উৎপাদন পাইপলাইনে ইনপুট হয় রাষ্ট্রীয় পরিবর্তনের উৎসগুলি এর মাধ্যমে প্রদান করতে পারে:

  • এক-শট অপারেশন যা সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস হতে পারে, উদাহরণস্বরূপ ফাংশন suspend জন্য কল।
  • স্ট্রীম API, উদাহরণস্বরূপ Flows
  • উপরের সবগুলো।

উপরের প্রতিটি ইনপুটগুলির জন্য আপনি কীভাবে একটি রাষ্ট্রীয় উত্পাদন পাইপলাইন একত্র করতে পারেন তা নিম্নলিখিত বিভাগগুলি কভার করে৷

রাষ্ট্র পরিবর্তনের উত্স হিসাবে এক-শট APIs

রাষ্ট্রের একটি পর্যবেক্ষণযোগ্য, পরিবর্তনযোগ্য ধারক হিসাবে MutableStateFlow API ব্যবহার করুন। Jetpack Compose অ্যাপে, আপনি mutableStateOf বিবেচনা করতে পারেন বিশেষ করে যখন কম্পোজ টেক্সট API-এর সাথে কাজ করেন। উভয় APIই এমন পদ্ধতি অফার করে যা আপডেটগুলি সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস হোক বা না হোক তাদের হোস্ট করা মানগুলিতে নিরাপদ পারমাণবিক আপডেটের অনুমতি দেয়।

উদাহরণস্বরূপ, একটি সাধারণ ডাইস রোলিং অ্যাপে রাষ্ট্রীয় আপডেটগুলি বিবেচনা করুন৷ ব্যবহারকারীর কাছ থেকে ডাইসের প্রতিটি রোল সিঙ্ক্রোনাস Random.nextInt() পদ্ধতি ব্যবহার করে এবং ফলাফলটি UI অবস্থায় লেখা হয়।

স্টেটফ্লো

data class DiceUiState(
    val firstDieValue: Int? = null,
    val secondDieValue: Int? = null,
    val numberOfRolls: Int = 0,
)

class DiceRollViewModel : ViewModel() {

    private val _uiState = MutableStateFlow(DiceUiState())
    val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()

    // Called from the UI
    fun rollDice() {
        _uiState.update { currentState ->
            currentState.copy(
            firstDieValue = Random.nextInt(from = 1, until = 7),
            secondDieValue = Random.nextInt(from = 1, until = 7),
            numberOfRolls = currentState.numberOfRolls + 1,
            )
        }
    }
}

রাজ্য রচনা করুন

@Stable
interface DiceUiState {
    val firstDieValue: Int?
    val secondDieValue: Int?
    val numberOfRolls: Int?
}

private class MutableDiceUiState: DiceUiState {
    override var firstDieValue: Int? by mutableStateOf(null)
    override var secondDieValue: Int? by mutableStateOf(null)
    override var numberOfRolls: Int by mutableStateOf(0)
}

class DiceRollViewModel : ViewModel() {

    private val _uiState = MutableDiceUiState()
    val uiState: DiceUiState = _uiState

    // Called from the UI
    fun rollDice() {
        _uiState.firstDieValue = Random.nextInt(from = 1, until = 7)
        _uiState.secondDieValue = Random.nextInt(from = 1, until = 7)
        _uiState.numberOfRolls = _uiState.numberOfRolls + 1
    }
}

অ্যাসিঙ্ক্রোনাস কল থেকে UI অবস্থা পরিবর্তন করা হচ্ছে

রাষ্ট্রীয় পরিবর্তনগুলির জন্য যেগুলির জন্য একটি অ্যাসিঙ্ক্রোনাস ফলাফলের প্রয়োজন, উপযুক্ত CoroutineScope এ একটি Coroutine চালু করুন৷ CoroutineScope বাতিল হয়ে গেলে এটি অ্যাপটিকে কাজটি বাতিল করার অনুমতি দেয়। স্টেট হোল্ডার তারপর সাসপেন্ড মেথড কলের ফলাফল UI স্টেট এক্সপোজ করতে ব্যবহৃত পর্যবেক্ষণযোগ্য API-এ লেখেন।

উদাহরণস্বরূপ, আর্কিটেকচার নমুনায় AddEditTaskViewModel বিবেচনা করুন। যখন স্থগিত করা saveTask() পদ্ধতি একটি টাস্ককে অ্যাসিঙ্ক্রোনাসভাবে সংরক্ষণ করে, তখন MutableStateFlow-এর update পদ্ধতিটি UI অবস্থায় স্টেট পরিবর্তনকে প্রচার করে।

স্টেটফ্লো

data class AddEditTaskUiState(
    val title: String = "",
    val description: String = "",
    val isTaskCompleted: Boolean = false,
    val isLoading: Boolean = false,
    val userMessage: String? = null,
    val isTaskSaved: Boolean = false
)

class AddEditTaskViewModel(...) : ViewModel() {

   private val _uiState = MutableStateFlow(AddEditTaskUiState())
   val uiState: StateFlow<AddEditTaskUiState> = _uiState.asStateFlow()

   private fun createNewTask() {
        viewModelScope.launch {
            val newTask = Task(uiState.value.title, uiState.value.description)
            try {
                tasksRepository.saveTask(newTask)
                // Write data into the UI state.
                _uiState.update {
                    it.copy(isTaskSaved = true)
                }
            }
            catch(cancellationException: CancellationException) {
                throw cancellationException
            }
            catch(exception: Exception) {
                _uiState.update {
                    it.copy(userMessage = getErrorMessage(exception))
                }
            }
        }
    }
}

রাজ্য রচনা করুন

@Stable
interface AddEditTaskUiState {
    val title: String
    val description: String
    val isTaskCompleted: Boolean
    val isLoading: Boolean
    val userMessage: String?
    val isTaskSaved: Boolean
}

private class MutableAddEditTaskUiState : AddEditTaskUiState() {
    override var title: String by mutableStateOf("")
    override var description: String by mutableStateOf("")
    override var isTaskCompleted: Boolean by mutableStateOf(false)
    override var isLoading: Boolean by mutableStateOf(false)
    override var userMessage: String? by mutableStateOf<String?>(null)
    override var isTaskSaved: Boolean by mutableStateOf(false)
}

class AddEditTaskViewModel(...) : ViewModel() {

   private val _uiState = MutableAddEditTaskUiState()
   val uiState: AddEditTaskUiState = _uiState

   private fun createNewTask() {
        viewModelScope.launch {
            val newTask = Task(uiState.value.title, uiState.value.description)
            try {
                tasksRepository.saveTask(newTask)
                // Write data into the UI state.
                _uiState.isTaskSaved = true
            }
            catch(cancellationException: CancellationException) {
                throw cancellationException
            }
            catch(exception: Exception) {
                _uiState.userMessage = getErrorMessage(exception))
            }
        }
    }
}

ব্যাকগ্রাউন্ড থ্রেড থেকে UI অবস্থা পরিবর্তন করা হচ্ছে

UI স্টেট তৈরির জন্য প্রধান প্রেরণকারীতে Coroutines চালু করা বাঞ্ছনীয়। অর্থাৎ নিচের কোড স্নিপেটে withContext ব্লকের বাইরে। যাইহোক, যদি আপনি একটি ভিন্ন ব্যাকগ্রাউন্ড প্রেক্ষাপটে UI অবস্থা আপডেট করতে চান, আপনি নিম্নলিখিত API ব্যবহার করে তা করতে পারেন:

  • একটি ভিন্ন সমসাময়িক প্রসঙ্গে Coroutines চালানোর জন্য withContext পদ্ধতি ব্যবহার করুন।
  • MutableStateFlow ব্যবহার করার সময়, যথারীতি update পদ্ধতি ব্যবহার করুন।
  • Compose State ব্যবহার করার সময়, Snapshot.withMutableSnapshot ব্যবহার করুন সমকালীন প্রসঙ্গে রাজ্যে পারমাণবিক আপডেটের নিশ্চয়তা দিতে।

উদাহরণস্বরূপ, নীচের DiceRollViewModel স্নিপেটে অনুমান করুন যে SlowRandom.nextInt() একটি গণনামূলকভাবে নিবিড় suspend ফাংশন যা একটি CPU আবদ্ধ Coroutine থেকে কল করা প্রয়োজন।

স্টেটফ্লো

class DiceRollViewModel(
    private val defaultDispatcher: CoroutineScope = Dispatchers.Default
) : ViewModel() {

    private val _uiState = MutableStateFlow(DiceUiState())
    val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()

  // Called from the UI
  fun rollDice() {
        viewModelScope.launch() {
            // Other Coroutines that may be called from the current context
            …
            withContext(defaultDispatcher) {
                _uiState.update { currentState ->
                    currentState.copy(
                        firstDieValue = SlowRandom.nextInt(from = 1, until = 7),
                        secondDieValue = SlowRandom.nextInt(from = 1, until = 7),
                        numberOfRolls = currentState.numberOfRolls + 1,
                    )
                }
            }
        }
    }
}

রাজ্য রচনা করুন

class DiceRollViewModel(
    private val defaultDispatcher: CoroutineScope = Dispatchers.Default
) : ViewModel() {

    private val _uiState = MutableDiceUiState()
    val uiState: DiceUiState = _uiState

  // Called from the UI
  fun rollDice() {
        viewModelScope.launch() {
            // Other Coroutines that may be called from the current context
            …
            withContext(defaultDispatcher) {
                Snapshot.withMutableSnapshot {
                    _uiState.firstDieValue = SlowRandom.nextInt(from = 1, until = 7)
                    _uiState.secondDieValue = SlowRandom.nextInt(from = 1, until = 7)
                    _uiState.numberOfRolls = _uiState.numberOfRolls + 1
                }
            }
        }
    }
}

রাষ্ট্র পরিবর্তনের উৎস হিসেবে স্ট্রিম APIs

রাষ্ট্রীয় পরিবর্তনের উত্সগুলির জন্য যা স্ট্রিমগুলিতে সময়ের সাথে সাথে একাধিক মান তৈরি করে, সমস্ত উত্সের আউটপুটগুলিকে একটি সমন্বিত সমগ্রে একত্রিত করা রাষ্ট্রীয় উত্পাদনের জন্য একটি সরল পদ্ধতি।

Kotlin Flows ব্যবহার করার সময়, আপনি কম্বাইন ফাংশন দিয়ে এটি অর্জন করতে পারেন। এর একটি উদাহরণ InterestsViewModel-এ "Now in Android" নমুনায় দেখা যেতে পারে:

class InterestsViewModel(
    authorsRepository: AuthorsRepository,
    topicsRepository: TopicsRepository
) : ViewModel() {

    val uiState = combine(
        authorsRepository.getAuthorsStream(),
        topicsRepository.getTopicsStream(),
    ) { availableAuthors, availableTopics ->
        InterestsUiState.Interests(
            authors = availableAuthors,
            topics = availableTopics
        )
    }
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5_000),
            initialValue = InterestsUiState.Loading
    )
}

StateFlows তৈরি করতে stateIn অপারেটরের ব্যবহার UI কে স্টেট প্রোডাকশন পাইপলাইনের কার্যকলাপের উপর সূক্ষ্ম দানাদার নিয়ন্ত্রণ দেয় কারণ এটি শুধুমাত্র তখনই সক্রিয় হতে পারে যখন UI দৃশ্যমান হয়।

  • SharingStarted.WhileSubscribed() ব্যবহার করুন যদি পাইপলাইন শুধুমাত্র তখনই সক্রিয় থাকে যখন জীবনচক্র-সচেতন পদ্ধতিতে প্রবাহ সংগ্রহ করার সময় UI দৃশ্যমান হয়।
  • SharingStarted.Lazily ব্যবহার করুন৷ অলসভাবে যদি পাইপলাইনটি সক্রিয় থাকে যতক্ষণ না ব্যবহারকারী UI এ ফিরে যেতে পারে, অর্থাৎ UI ব্যাকস্ট্যাকে বা অন্য ট্যাব অফস্ক্রিনে রয়েছে৷

রাজ্যের সমষ্টিগত স্ট্রীম ভিত্তিক উত্সগুলি প্রযোজ্য নয় এমন ক্ষেত্রে, কোটলিন ফ্লোসের মতো স্ট্রীম APIগুলি UI রাজ্যে স্ট্রীমগুলিকে প্রক্রিয়াকরণে সহায়তা করার জন্য একত্রিতকরণ , সমতলকরণ এবং আরও কিছু রূপান্তরের একটি সমৃদ্ধ সেট অফার করে৷

এক-শট এবং স্ট্রিম এপিআই রাষ্ট্র পরিবর্তনের উত্স হিসাবে

যে ক্ষেত্রে রাষ্ট্রীয় উৎপাদন পাইপলাইন রাষ্ট্রীয় পরিবর্তনের উৎস হিসাবে এক-শট কল এবং স্ট্রীম উভয়ের উপর নির্ভর করে, স্ট্রিমগুলি হল সংজ্ঞায়িত সীমাবদ্ধতা। অতএব, ওয়ান-শট কলগুলিকে স্ট্রীম API-এ রূপান্তর করুন, বা তাদের আউটপুটগুলিকে স্ট্রীমে পাইপ করুন এবং উপরের স্ট্রিম বিভাগে বর্ণিত প্রক্রিয়াকরণ পুনরায় শুরু করুন।

প্রবাহের সাথে, এর অর্থ সাধারণত রাষ্ট্রীয় পরিবর্তনগুলি প্রচার করতে এক বা একাধিক ব্যক্তিগত ব্যাকিং MutableStateFlow দৃষ্টান্ত তৈরি করা। আপনি রচনা অবস্থা থেকে স্ন্যাপশট প্রবাহও তৈরি করতে পারেন।

নীচের আর্কিটেকচার-নমুনা সংগ্রহস্থল থেকে TaskDetailViewModel বিবেচনা করুন:

স্টেটফ্লো

class TaskDetailViewModel @Inject constructor(
    private val tasksRepository: TasksRepository,
    savedStateHandle: SavedStateHandle
) : ViewModel() {

    private val _isTaskDeleted = MutableStateFlow(false)
    private val _task = tasksRepository.getTaskStream(taskId)

    val uiState: StateFlow<TaskDetailUiState> = combine(
        _isTaskDeleted,
        _task
    ) { isTaskDeleted, task ->
        TaskDetailUiState(
            task = taskAsync.data,
            isTaskDeleted = isTaskDeleted
        )
    }
        // Convert the result to the appropriate observable API for the UI
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5_000),
            initialValue = TaskDetailUiState()
        )

    fun deleteTask() = viewModelScope.launch {
        tasksRepository.deleteTask(taskId)
        _isTaskDeleted.update { true }
    }
}

রাজ্য রচনা করুন

class TaskDetailViewModel @Inject constructor(
    private val tasksRepository: TasksRepository,
    savedStateHandle: SavedStateHandle
) : ViewModel() {

    private var _isTaskDeleted by mutableStateOf(false)
    private val _task = tasksRepository.getTaskStream(taskId)

    val uiState: StateFlow<TaskDetailUiState> = combine(
        snapshotFlow { _isTaskDeleted },
        _task
    ) { isTaskDeleted, task ->
        TaskDetailUiState(
            task = taskAsync.data,
            isTaskDeleted = isTaskDeleted
        )
    }
        // Convert the result to the appropriate observable API for the UI
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5_000),
            initialValue = TaskDetailUiState()
        )

    fun deleteTask() = viewModelScope.launch {
        tasksRepository.deleteTask(taskId)
        _isTaskDeleted = true
    }
}

রাষ্ট্রীয় উৎপাদন পাইপলাইনে আউটপুট প্রকার

UI অবস্থার জন্য আউটপুট API-এর পছন্দ এবং এর উপস্থাপনার প্রকৃতি মূলত আপনার অ্যাপ UI রেন্ডার করতে যে API ব্যবহার করে তার উপর নির্ভর করে। অ্যান্ড্রয়েড অ্যাপে, আপনি ভিউ বা জেটপ্যাক কম্পোজ ব্যবহার করতে পারেন। এখানে বিবেচনার মধ্যে রয়েছে:

নিম্নলিখিত সারণীটি সংক্ষিপ্ত করে যে কোন প্রদত্ত ইনপুট এবং ভোক্তার জন্য আপনার রাজ্য উত্পাদন পাইপলাইনের জন্য কী API ব্যবহার করতে হবে:

ইনপুট ভোক্তা আউটপুট
এক-শট API ভিউ StateFlow বা LiveData
এক-শট API রচনা করা StateFlow বা কম্পোজ State
স্ট্রিম API ভিউ StateFlow বা LiveData
স্ট্রিম API রচনা করা StateFlow
এক-শট এবং স্ট্রিম API ভিউ StateFlow বা LiveData
এক-শট এবং স্ট্রিম API রচনা করা StateFlow

রাজ্য উত্পাদন পাইপলাইন সূচনা

রাষ্ট্রীয় উত্পাদন পাইপলাইন শুরু করার সাথে পাইপলাইন চালানোর জন্য প্রাথমিক শর্তগুলি সেট করা জড়িত। এতে পাইপলাইন শুরু করার জন্য গুরুত্বপূর্ণ প্রাথমিক ইনপুট মান প্রদান করা জড়িত থাকতে পারে, উদাহরণস্বরূপ একটি সংবাদ নিবন্ধের বিশদ দৃশ্যের জন্য একটি id , বা একটি অ্যাসিঙ্ক্রোনাস লোড শুরু করা।

সিস্টেম রিসোর্স সংরক্ষণ করার জন্য আপনার অলসভাবে রাষ্ট্রীয় উৎপাদন পাইপলাইন শুরু করা উচিত। কার্যত, এর অর্থ প্রায়শই আউটপুটের একজন ভোক্তা না হওয়া পর্যন্ত অপেক্ষা করা। Flow এপিআই stateIn পদ্ধতিতে started আর্গুমেন্টের সাথে এটির অনুমতি দেয়। যে ক্ষেত্রে এটি প্রযোজ্য নয়, নিম্নলিখিত স্নিপেটে দেখানো হিসাবে স্পষ্টভাবে রাজ্য উত্পাদন পাইপলাইন শুরু করার জন্য একটি idempotent initialize() ফাংশন সংজ্ঞায়িত করুন:

class MyViewModel : ViewModel() {

    private var initializeCalled = false

    // This function is idempotent provided it is only called from the UI thread.
    @MainThread
    fun initialize() {
        if(initializeCalled) return
        initializeCalled = true

        viewModelScope.launch {
            // seed the state production pipeline
        }
    }
}

নমুনা

নিম্নলিখিত Google নমুনাগুলি UI স্তরে রাজ্যের উত্পাদন প্রদর্শন করে৷ অনুশীলনে এই নির্দেশিকা দেখতে তাদের অন্বেষণ করুন:

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}