簡體   English   中英

如何用 Flow 替換 LiveData

[英]How to replace LiveData with Flow

我有一個名為sortOrderLiveData ,然后我有另一個名為myData的變量,它觀察對sortOrder的任何更改並相應地填充數據。

class TestViewModel @ViewModelInject constructor() : ViewModel() {

    private val sortOrder = MutableLiveData<String>()

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }

    init {
        sortOrder.value = "year"
    }

}

在活動中觀察

class TestActivity : AppCompatActivity() {

    private val viewModel: TestViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        
        // Observing data
        viewModel.myData.observe(this) {
            Timber.d("Data is : $it")
        }
    }
}

  • 如何在 output 中沒有任何變化的情況下用Flow/StateFlow API 替換上述場景?

如果您無法將映射的冷流轉換為熱流,它會在您每次收集它時重新啟動流(就像重新創建 Activity 時一樣)。 這就是冷流的工作原理。

我有一種感覺,他們會充實 StateFlow/SharedFlow 的轉換函數,因為將它們轉換為冷流並不得不將它們轉回熱流感覺非常尷尬。

如果您不想手動 map 明確第一個元素,則公共 Flow 必須是 SharedFlow,因為stateIn function 要求您直接提供初始 state。

    private val sortOrder = MutableStateFlow("year")

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }.shareIn(viewModelScope, SharingStarted.Eagerly, 1)

或者您可以創建一個單獨的 function,它在map中調用,也在stateIn function 調用中調用。

    private val sortOrder = MutableSharedFlow<String>()
    
    private fun convertSortOrder(order: String): String {
        Log.d("ViewModel", "Sort order changed to $order")
        return "Sort order is $order"
    }

    val myData = sortOrder.map {
        convertSortOrder(it)
    }.stateIn(viewModelScope, SharingStarted.Eagerly, convertSortOrder("year"))

我有一個名為sortOrderLiveData ,然后我有另一個名為myData的變量,它觀察對sortOrder的任何更改並相應地填充數據。

class TestViewModel @ViewModelInject constructor() : ViewModel() {

    private val sortOrder = MutableLiveData<String>()

    val myData = sortOrder.map {
        Timber.d("Sort order changed to $it")
        "Sort order is $it"
    }

    init {
        sortOrder.value = "year"
    }

}

在活動中觀察

class TestActivity : AppCompatActivity() {

    private val viewModel: TestViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        
        // Observing data
        viewModel.myData.observe(this) {
            Timber.d("Data is : $it")
        }
    }
}

問題

  • 如何在不更改 output 的情況下用Flow/StateFlow API 替換上述場景?

從片段/活動的角度來看,您必須創建一個作業來收集onStart()中的流並在onStop()中取消它。 使用lifecycleScope.launchWhenStarted將使流即使在后台也保持活動狀態

使用綁定庫輕松遷移到Flow 我有偏見,不過。

請參閱有關它的媒體文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM