目录
- 一、简介
- 1.1 优点
- 1.2 生命周期
- 二、使用
- 2.1 ViewModel保证数据稳定性demo
- 2.2 ViewModel中如何传递上下文Context
- 三、注意点
一、简介
ViewModel 组件用于管理界面相关的数据,并且在配置更改(如屏幕旋转)时保持数据的一致性。ViewModel 组件的详细解释如下:
作用
:
ViewModel 用于存储和管理界面相关的数据,如 UI 元素的状态、用户交互数据等。
通过 ViewModel 可以在界面控制器(如 Activity 或 Fragment)之间共享数据,而无需担心生命周期问题。特点
:
ViewModel 对象会在相关的 Activity 或 Fragment 生命周期内保持不变,即使配置更改也不会丢失数据。
ViewModel 不持有对界面控制器的引用,因此不会造成内存泄漏。
ViewModel 适用于存储大量数据或需要跨界面共享的数据。使用方法
:
在 Activity 或 Fragment 中通过 ViewModelProvider 获取 ViewModel 对象。
在 ViewModel 中编写逻辑代码,如数据获取、数据处理等。
在界面控制器中观察 ViewModel 中的数据变化,并更新 UI。
画一个简单示意图
1.1 优点
使用 ViewModel 来保存和管理应用程序的数据具有以下好处:
生命周期感知
:ViewModel 对象会感知与其关联的 Activity 或 Fragment 的生命周期,并在这些组件被销毁时保留数据状态。这样可以避免在配置更改或屏幕旋转等情况下丢失数据。数据共享
:ViewModel 可以在不同的组件之间共享数据,例如在 Fragment 和 Activity 之间共享数据。这样可以避免数据重复加载和保持数据一致性。避免内存泄漏
:使用 ViewModel 可以避免由于内存泄漏而导致的性能问题。ViewModel 会在不再需要时自动清理资源,确保不会造成内存泄漏。简化代码
:将数据存储和管理的责任交给 ViewModel,可以使代码更加清晰和简洁。ViewModel 可以帮助分离数据处理逻辑和 UI 展示逻辑,提高代码的可维护性和可读性。支持配置更改
:ViewModel 可以帮助应对配置更改(如屏幕旋转)时的数据保存和恢复问题,确保用户体验的连续性。
1.2 生命周期
二、使用
2.1 ViewModel保证数据稳定性demo
用一个简单得例子比较使用ViewModel保存数据的好处
MyViewModel
继承自ViewModel ,写一个int型属性
public class MyViewModel extends ViewModel {
public int number = 0;
/**
* 释放资源
*/
@Override
protected void onCleared() {
super.onCleared();
}
}
ViewModelActivity
两个方法,分别用NoViewModel和UseViewModel观察在横竖屏情况下显示数据的稳定性
public class ViewModelActivity extends AppCompatActivity {
ActivityViewmodelBinding binding;
private MyViewModel myViewModel;
private int mynumber = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityViewmodelBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory())
.get(MyViewModel.class);
NoViewModel();
}
public void NoViewModel() {
binding.viewmodeltext.setText(String.valueOf(mynumber));
binding.viewmodel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.viewmodeltext.setText(String.valueOf(++mynumber));
}
});
}
public void UseViewModel() {
binding.viewmodeltext.setText(String.valueOf(myViewModel.number));
binding.viewmodel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
binding.viewmodeltext.setText(String.valueOf(++myViewModel.number));
}
});
}
}
NoViewModel
UseViewModel
怎么样?对比是不是很明显。
2.2 ViewModel中如何传递上下文Context
ViewModel既然能管理我们的数据,那么Activity、Fragment中数据的传递必然会用到上下文Context了,ViewModel如何去获取呢?
这时候需要继承的对象不再是ViewModel了,而是AndroidViewModel
根据提示完成构造器
在构造器中传递context,当后续使用context的时候便可以使用了。
public class MyViewModel extends AndroidViewModel {
Context context;
public int number = 0;
public MyViewModel(@NonNull Application application) {
super(application);
context =application;
}
}
三、注意点
在开发中不会单独使用ViewModel ,一般是与LiveData等其他JetPack组件综合使用的,以下是ViewModel 使用过程中的注意事项:
生命周期感知
:ViewModel 是与生命周期绑定的,因此应该避免在 ViewModel 中持有对界面元素(如 Activity、Fragment)的引用,以防止内存泄漏。如果需要使用 Context,请考虑使用 Application Context 或者 AndroidViewModel。避免存储大量数据
:ViewModel 主要用于存储与界面相关的数据,不应该存储大量数据或长期保持数据。对于大量数据或需要长期保存的数据,应该考虑使用其他方式,如 Room 数据库。避免过度耦合
:ViewModel 应该专注于管理界面相关的数据和业务逻辑,而不应该包含太多与界面无关的逻辑。保持 ViewModel 的职责单一,可以使代码更易于维护和测试。使用 LiveData
:ViewModel 中通常会使用 LiveData 来持有数据,以便在数据发生变化时通知界面更新。LiveData 具有生命周期感知能力,可以确保数据更新时只通知处于活动状态的界面。避免内存泄漏
:在编写 ViewModel 时,要注意避免引起内存泄漏的情况。确保及时释放资源和取消不再需要的订阅或回调,以避免造成内存泄漏。
参考链接:
ViewModel的基本使用
ViewModel简单使用与解析
深入理解与运用Android Jetpack ViewModel