我有一个单独的类来处理数据提取(特别是Firebase),我通常从它返回LiveData对象并异步更新它们.现在我想将返回的数据存储在ViewModel中,但问题是为了获得所述值,我需要观察从我的数据获取类返回的LiveData对象.observe方法需要一个LifecycleOwner对象作为第一个参数,但我显然没有在我的ViewModel内部,我知道我不应该保持对ViewModel内部的Activity/Fragment的引用.我该怎么办?
android android-livedata android-viewmodel android-architecture-components
我有一个片段:
class MyFragment : BaseFragment() {
// my StudentsViewModel instance
lateinit var viewModel: StudentsViewModel
override fun onCreateView(...){
...
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this).get(StudentsViewModel::class.java)
updateStudentList()
}
fun updateStudentList() {
// Compiler error on 'this': Use viewLifecycleOwner as the LifecycleOwner
viewModel.students.observe(this, Observer {
//TODO: populate recycler view
})
}
}
Run Code Online (Sandbox Code Playgroud)
在我的片段中,我有一个 StudentsViewModel 的实例,它在onViewCreated(...).
在,StudentsViewModel,students是一个LiveData:
class StudentsViewModel : ViewModel() {
val students = liveData(Dispatchers.IO) {
...
} …Run Code Online (Sandbox Code Playgroud) android android-fragments android-livedata android-viewmodel
谁能建议如何在 Jetpack Compose Navigation 的不同部分中共享 ViewModel?
根据文档,viewModel 通常应该使用活动范围在不同的 compose 函数中共享,但如果在导航内部则不然。
这是我试图修复的代码。看起来我在导航内的两个部分中获得了两个不同的 viewModel:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NavigationSystem()
}
}
}
@Composable
fun NavigationSystem() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("result") { ResultScreen(navController) }
}
}
@Composable
fun HomeScreen(navController: NavController) {
val viewModel: ConversionViewModel = viewModel()
var temp by remember { mutableStateOf("") }
val fahrenheit = temp.toIntOrNull() ?: 0
Column(
modifier = …Run Code Online (Sandbox Code Playgroud) android-viewmodel android-jetpack-navigation android-jetpack-compose
参考android.arch.lifecycle.ViewModel课程.
ViewModel限定在与其相关的UI组件的生命周期中,因此在Fragment基于应用程序的应用程序中,这将是片段生命周期.这是一件好事.
在某些情况下,人们想要ViewModel在多个片段之间共享实例.具体而言,我对许多屏幕与相同基础数据相关的情况感兴趣.
(当多个相关片段显示在同一个屏幕上时,文档提出了相似的方法,但这可以通过使用单个宿主片段来解决,如下面的答案所示.)
这在官方ViewModel文档中讨论:
ViewModels还可以用作活动的不同片段之间的通信层.每个Fragment都可以通过其Activity使用相同的密钥获取ViewModel.这允许以解耦方式在片段之间进行通信,使得它们永远不需要直接与其他片段对话.
换句话说,要在表示不同屏幕的片段之间共享信息,ViewModel应将其范围限定为Activity生命周期(并且根据Android文档,这也可以在其他共享实例中使用).
现在,在新的Jetpack导航模式中,建议使用"One Activity/Many Fragments"架构.这意味着活动在应用程序使用的整个过程中都存在.
即任何ViewModel作用于Activity生命周期的共享实例永远不会被清除 - 内存仍然在不断使用.
为了保留内存并在任何时间点使用尽可能少的内容,能够ViewModel在不再需要时清除共享实例会很好.
如何ViewModel从它ViewModelStore或持有者片段手动清除?
android android-viewmodel android-architecture-components android-jetpack
我们如何将参数传递给viewModelin Jetpack Compose?
这是我的可组合项
@Composable
fun UsersList() {
val myViewModel: MyViewModel = viewModel("db2name") // pass param like this
}
Run Code Online (Sandbox Code Playgroud)
这是viewModel
class MyViewModel(private val dbname) : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
MutableLiveData<List<User>>().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用带有LiveData的Android MVVM架构.我有一个像这样的对象
public class User {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Run Code Online (Sandbox Code Playgroud)
我的视图模型看起来像这样
public class InfoViewModel extends AndroidViewModel {
MutableLiveData<User> user = new MutableLiveData<>();
public InfoViewModel(@NonNull Application application) {
super(application);
User user = new User();
user.setFirstName("Alireza");
user.setLastName("Ahmadi");
this.user.setValue(user);
}
public LiveData<User> getUser(){
return user;
}
public void …Run Code Online (Sandbox Code Playgroud) 在查看的Google文档时ViewModel,他们显示了以下有关如何获取的示例代码ViewModel:
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
使用最新的依赖项时android.arch.lifecycle:extensions:1.1.1,没有此类ViewModelProviders。
要在文档的ViewModelProviders,我看到一个评论说:
在API级别1.1.0中不推荐使用该类。使用ViewModelProvider.AndroidViewModelFactory
问题是,当尝试使用时ViewModelProvider.AndroidViewModelFactory,无法找到等效的of方法来获取的实例ViewModel。
我尝试做的是:
ViewModelProvider.AndroidViewModelFactory.getInstance(application).create(PlayerViewHolder::class.java)
Run Code Online (Sandbox Code Playgroud)
因此,方法的名称create每次调用时都会得到一个ViewModel的新实例,这不是我想要的。
有什么想法可以替换上面不推荐使用的代码吗?
android android-gradle-plugin android-viewmodel android-architecture-components
在 Dagger Hilt View Model 1.0.0-alpha01 中
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01"
implementation 'com.google.dagger:hilt-android:2.28-alpha'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
kapt 'com.google.dagger:hilt-android-compiler:2.28-alpha'
Run Code Online (Sandbox Code Playgroud)
我可以使用下面的
class MyViewModel @ViewModelInject constructor(
private val repository: Repository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel(), LifecycleObserver {
// Some codes...
}
Run Code Online (Sandbox Code Playgroud)
但是,当我迁移到 Dagger Hilt View Model 1.0.0-alpha03 时
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
implementation 'com.google.dagger:hilt-android:2.31.2-alpha'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
kapt 'com.google.dagger:hilt-android-compiler:2.31.2-alpha'
Run Code Online (Sandbox Code Playgroud)
我收到了警告
'Assisted' is deprecated. Deprecated in Java
'ViewModelInject' is deprecated. Deprecated in Java
'ViewModelInject' is deprecated. Deprecated in Java
'Assisted' is deprecated. Deprecated in Java
Run Code Online (Sandbox Code Playgroud)
有什么新的工作方式?
ViewModels是独立于活动/片段生命周期还是仅与其配置更改无关.什么时候它们将不复存在并且后续的onCleared()方法被调用.viewModel可以与另一个Activity共享吗?
情况:
Activity1+viewModel1--->(rotation)--->Activity1+viewModel1
--->(launch Intent)--->Activity2+viewModel1
Run Code Online (Sandbox Code Playgroud)
这种分享是否可能,这是一种很好的做法.
此外,由于应用程序生命周期回调,onPause-> onStop-> onDestroy对于两者都是相同的
1.活动旋转和
2.活动结束时,
ViewModel如何在内部确定调用onCleared并最终结束其生命周期的正确时间.
调查结果:
ViewModel在内部使用holderFragment来保存活动的实例,并使用setRetainInstance方法(如片段)来考虑配置更改.
android android-lifecycle android-activity android-viewmodel
我有一个关于android ViewModels的架构问题:
假设我的应用程序中有一个包含两个片段的Activity(使用Viewpager).这两个片段做了不同的事情(因此可能有自己的ViewModel?),但它们也需要各种类似的数据.
例如,如果网络连接可用或不存在(并且两个片段在没有连接的情况下显示不同的错误UI),或者某些用户设置来自服务器并且同等地影响两个片段,则这是状态.
这看起来像这样:
现在我的问题是如何在使用ViewModels时处理这种情况?视图是否观察多个ViewModel是好的,就像我有一个ViewModel用于Activity(保持两个都需要的状态)和每个片段一个,如下所示:
这在这里暗示,但这不是一个好的做法,因为MVVM中的关系通常是
查看n - 1 ViewModel n - 1模型
但我不确定这种共享LiveData的正确位置在哪里?