ViewModel 具有生命周期感知的特性,这是它在 Android 架构中一个非常重要的优势。
ViewModel 的生命周期与 Android 组件(如 Activity 或 Fragment)的生命周期相关联,但又有所不同。
当关联的 Activity 或 Fragment 首次创建时,对应的 ViewModel 也会被创建。然而,与视图组件不同的是,ViewModel 在配置更改(如屏幕旋转)时不会被销毁和重新创建。这是因为配置更改导致的视图重建通常只是为了适应新的屏幕方向或其他配置变化,而与数据和业务逻辑无关。
这种特性使得 ViewModel 能够在配置更改期间保留其内部的数据和状态。例如,如果在一个 Activity 中正在加载数据,当屏幕旋转时,数据加载的进度和已经获取到的数据可以在 ViewModel 中得以保存,而无需重新开始加载。
只有当关联的 Activity 或 Fragment 真正完成使命被系统销毁时,ViewModel 才会随之被清除,释放相关资源。
生命周期感知的好处在于:
- 提高性能:避免了在不必要的情况下重复执行数据加载和初始化操作,节省了系统资源和时间。
- 增强用户体验:用户不会因为配置更改而丢失当前的操作进度和数据状态。
- 简化代码逻辑:开发者无需在视图组件中处理复杂的配置更改时的数据保存和恢复逻辑,专注于视图的展示和交互逻辑。
总之,ViewModel 的生命周期感知特性为构建稳定、高效和用户友好的 Android 应用提供了有力的支持。
示例
以下是一个简单的示例,展示了 ViewModel
如何与 Activity
的生命周期相关联,并在生命周期变化时正确管理数据:
首先创建一个 ViewModel
类:
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
private int counter;
public int getCounter() {
return counter;
}
public void incrementCounter() {
counter++;
}
}
然后在 Activity
中使用这个 ViewModel
:
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
public class MainActivity extends AppCompatActivity {
private MyViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
// 初始时显示计数器的值
updateCounterText();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 在 Activity 销毁时,ViewModel 也会被清理
}
private void updateCounterText() {
// 更新界面上显示计数器值的文本
TextView counterTextView = findViewById(R.id.counterTextView);
counterTextView.setText(String.valueOf(viewModel.getCounter()));
}
public void incrementCounter(View view) {
viewModel.incrementCounter();
updateCounterText();
}
}
在上述示例中:
- 在
onCreate
方法中获取ViewModel
的实例。 - 当用户点击按钮触发
incrementCounter
方法时,ViewModel
中的计数器值增加。 - 无论
Activity
经历何种生命周期变化(如旋转屏幕),ViewModel
中的计数器数据都会被保存,不会丢失。 - 当
Activity
真正被销毁时,ViewModel
也会随之被合理清理。
从源码角度说说viewmodel的生命周期感知
要从源码角度理解 ViewModel 的生命周期感知,需要深入研究 Android Jetpack 中 ViewModel 的实现机制。
ViewModel 能够感知 Android 组件(如 Activity 或 Fragment)的生命周期,主要依赖于 ViewModelStore
和 ViewModelStoreOwner
这两个关键类。
ViewModelStore
用于存储 ViewModel 实例。在 Activity 或 Fragment 中,通过实现 ViewModelStoreOwner
接口,来获取和管理 ViewModelStore
。
当 Activity 或 Fragment 被创建时,会获取对应的 ViewModelStore
,并将创建的 ViewModel 实例添加到其中进行存储。
在生命周期变化时,例如配置更改导致 Activity 或 Fragment 重建,系统会重新获取之前保存的 ViewModelStore
,从而能够获取到之前创建并存储在其中的 ViewModel 实例,实现了数据的保留和复用。
从源码来看,关键的方法如 getViewModelStore
用于获取 ViewModelStore
对象,saveViewModelState
和 restoreViewModelState
等方法用于在适当的时机保存和恢复 ViewModel 的状态。
总的来说,ViewModel 的生命周期感知是通过精心设计的存储机制和与 Android 组件生命周期的紧密结合来实现的,确保了数据的稳定性和应用的性能优化。