LiveData似乎非常有用,因为它只在视图处于活动状态时通知视图。它还在订阅后立即存储并返回最后一个值给新订阅者。
我的问题是如何仅使用 RxJava 实现相同的功能?
由于 Rx 是一个功能齐全的反应式解决方案,将它与另一个反应式解决方案结合起来似乎不太对。我更喜欢是否可以从项目中删除 LiveData。
我知道https://github.com/trello/RxLifecycle和https://github.com/uber/AutoDispose但他们所做的是取消订阅流。我不想要那个。只要视图模型还活着,我就希望我的流存在,但我的活动会根据生命周期开始和停止收听 Steam。
任何建议将不胜感激
我从这里开始学习从Google指南实施MVVM:https:
//codelabs.developers.google.com/codelabs/android-room-with-a-view/#8 (特别是对我感兴趣的页面发布链接) .
由于我理解在Java中实现它,我决定切换到Kotlin.在类扩展中初始化构造函数时,AndroidViewModel我需要调用super它,它会抛出以下错误:
"super"不是表达,它只能用在点的左侧('.')"
当我用Google搜索并发现类似的主题但我根本不理解它,所以我没有解决我的问题.这是我的ViewModel课程代码:
class NotesViewModel private constructor(application: Application) : AndroidViewModel(application){
var mRepository: NotesRepository? = null
var mAllNotes: LiveData<List<Notes>>? = null
init {
super(application) // <-- here it throws me an error
mRepository = NotesRepository(application)
mAllNotes = mRepository!!.getAllWords()
}
fun getAllNotes(): LiveData<List<Notes>>{
return mAllNotes!!
}
fun insert(notes: Notes){
mRepository!!.insert(notes)
}
}
Run Code Online (Sandbox Code Playgroud)
那么,我该如何正确调用super,构造一个构造函数呢?这是这个类的正确java代码:
public class WordViewModel extends AndroidViewModel {
private WordRepository mRepository;
private LiveData<List<Word>> mAllWords;
public WordViewModel(Application application) …Run Code Online (Sandbox Code Playgroud) 我使用 LiveData 显示 Room 中表中的记录数。我调用一个函数来检索该计数,并在收到该计数后调用观察者来显示该计数。这按预期工作。但我还运行一个服务,该服务从后端检索数据并将其存储在我从中读取计数的同一个表中。但是每当存储数据时,每次都会调用可观察对象并更新显示的计数。我不知道为什么会发生这种情况。事实上我确实希望这一切发生。我只是不明白为什么会发生这种情况。当我运行代码来检索计数时,它是使用 RxJava 完成的。因此,当调用完成时,我看不出为什么计数的可观察值会随着每个数据存储而更新。唯一可能的原因是 Room 会跟踪我的计数查询并在存储数据时执行它。那可能吗?这是我获取计数的代码:
在我的片段中观察到:
viewModel.onConnectionsCountRetrieved.observe(this, Observer { count ->
var title = getString(R.string.connections)
if (count > 0)
title += " (" + "%,d".format(count) + ")"
(activity as MainActivity).getSupportActionBar()?.title = title
})
Run Code Online (Sandbox Code Playgroud)
在我的视图模型中:
val onConnectionsCountRetrieved: MutableLiveData<Int> = MutableLiveData()
@SuppressLint("CheckResult")
fun getConnectionsCount() {
val disposable = connectionsBO.getConnectionsCount()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ count -> onConnectionsCountRetrieved.postValue(count) },
{ ex -> App.context.displayErrorMessage(R.string.problem_retrieving_total_connection_count) }
)
disposables.add(disposable)
}
Run Code Online (Sandbox Code Playgroud) 我最近检查了 livedata 协程,发现了一些我无法理解的东西。为什么这段代码(观察时)没有冻结 UI?
val lv =
liveData (context=Dispatchers.Main){
var x = 0
while (true){
emit(x++)
delay(1000)
println(Thread.currentThread().name)
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
我在 Kotlin 中使用 MVVM 架构。我创建了一个 ViewModel 和 Repository 类。在 Repository 类中,我使用改造从 API 获取数据。我将该数据存储到我的 MutableLiveData 对象中,但是在调试对象时,即使我的 response.body 不为 null,该对象也始终显示为 null。
我对 Kotlin 很陌生。请帮忙..
ItemRepository.kt
class ItemRepository {
companion object{
private var instance: ItemRepository? = null
private var itemMutableList: MutableLiveData<List<ItemItem>>? = null
fun getinstance(): ItemRepository {
if (instance == null){
instance = ItemRepository()
}
return instance as ItemRepository
}
}
fun getItems() :MutableLiveData<List<ItemItem>>?{
var itemCall : Call<List<ItemItem>?> = ApiClient.getInstance()!!.getApi()!!.getIteams();
itemCall.enqueue(object : Callback<List<ItemItem>?> {
override fun onFailure(call: Call<List<ItemItem>?>, t: Throwable) {
}
override …Run Code Online (Sandbox Code Playgroud) 目前我在我的应用程序中有这种方法:
ViewState(每个屏幕一个视图状态)
sealed class CategoriesViewState {
object Loading : CategoriesViewState()
data class Error(
val errorMessage: String,
val messageType: UIComponentType
) : CategoriesViewState()
data class CategoryList(
val categories: List<Category>
) : CategoriesViewState()
}
Run Code Online (Sandbox Code Playgroud)
我使用实时数据在我的片段/活动中观察这种状态:
viewModel.viewState.observe(viewLifecycleOwner, Observer {
when (it) {
is CategoriesViewState.Loading -> {
progress_bar.visibility = View.VISIBLE
Log.d(TAG, "LOADING")
}
is CategoriesViewState.Error -> {
progress_bar.visibility = View.GONE
Log.d(TAG, "ERROR")
}
is CategoriesViewState.CategoryList -> {
progress_bar.visibility = View.GONE
Log.d(TAG, "DATA")
}
}
})
Run Code Online (Sandbox Code Playgroud)
它工作正常。
但在我看来,随着应用程序的增长,效率很低。
假设我的应用程序中有 20 个屏幕:我需要 20 个视图状态,我需要在每个屏幕中编写相同的 …
android mvvm kotlin android-livedata android-architecture-components
我正在使用 OkHttp 库从互联网下载一些数据,然后androidx.lifecycle.ViewModel
我想更新我的LiveData. 似乎从后台线程执行此操作会引发异常,如下所示:
2022-01-17 15:47:59.589 7354-7396/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.example.myapplication, PID: 7354
java.lang.IllegalStateException: Cannot invoke setValue on a background thread
at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:487)
at androidx.lifecycle.LiveData.setValue(LiveData.java:306)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at com.example.myapplication.MainActivityViewModel$getOneMoreCat$1.invoke(MainActivityViewModel.kt:86)
at com.example.myapplication.MainActivityViewModel$getOneMoreCat$1.invoke(MainActivityViewModel.kt:39)
at com.example.myapplication.singleton.CommunicationManager$sendRequest$1.onResponse(CommunicationManager.kt:24)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Run Code Online (Sandbox Code Playgroud)
现在我找到了两种不同的方法来调度到主线程ViewModel(根据 AAC 指南,它没有引用 Context),请参见此处:
GlobalScope.launch {
withContext(Dispatchers.Main) {
// do whatever, e.g. update LiveData
}
}
Run Code Online (Sandbox Code Playgroud)
或者
Handler(Looper.getMainLooper()).post(Runnable {
// do whatever, e.g. update LiveData
})
Run Code Online (Sandbox Code Playgroud)
哪个是正确的方法?也就是说,在运行时影响最小。
更新我确实发现我也可以这样做myLiveData.post() …
android kotlin android-livedata kotlin-coroutines coroutinescope
livedata 和 mutableLiveData 有什么区别?什么时候双方都能观察到新值?
android ×8
kotlin ×6
mvvm ×4
rx-java ×2
android-architecture-components ×1
android-room ×1
java ×1
retrofit ×1