JetPack之ViewModel


一、简介

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

  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值