android更新ui内存泄露,Android官方实用类更新ViewDataBinding+DiffUtil+LiveData+ViewModel等...

ViewDataBinding

可用于绑定Activity/Fragement等,相似于ButterKnife,好处在于把Activity的逻辑与布局的实现完全分离,布局相关逻辑所有转移到XXXViewdataBindng中。网络

并且DataBinding比ButterKnife效率高ide

DiffUtil

DiffUtil是support-v7:24.2.0推出的工具,用来寻找新旧两个数据集的最小变化量,主要使用场景是recycleView的更新,针对RecycleView全局更新的主要缺点:函数

不会触发RecyclerView的动画(删除、新增、位移、change动画)

性能较低,毕竟是无脑的刷新了一遍整个RecyclerView , 极端状况下:新老数据集如出一辙,效率是最低的。

经过DiffUtil能轻松实现recycleView的差量刷新。工具

主要使用方式以下:布局

DiffUtil.DiffResult result = DiffUtil.calculateDiff(newDiffUtil.Callback() {@Overridepublic intgetOldListSize() {returnmProductList.size();}@Overridepublic intgetNewListSize() {returnproductList.size();}@Overridepublic booleanareItemsTheSame(intoldItemPosition, intnewItemPosition) {//经过惟一标识判断是否同一数据

returnmProductList.get(oldItemPosition).getId() ==productList.get(newItemPosition).getId();}@Overridepublic booleanareContentsTheSame(intoldItemPosition, intnewItemPosition) {//如果同一数据,再比较它内部有没有更新

Product newProduct =productList.get(newItemPosition);Product oldProduct =mProductList.get(oldItemPosition);

returnnewProduct.getId() == oldProduct.getId()

&& Objects.equals(newProduct.getDescription(),oldProduct.getDescription())

&& Objects.equals(newProduct.getName(),oldProduct.getName())

&& newProduct.getPrice() == oldProduct.getPrice();性能

//上面通常状况能够在在实体类中实现equal接口,而后直接return o1.equals(o2)}

});

mProductList= productList;

result.dispatchUpdatesTo(this);动画

使用以上的方式能够经过diffResult.dispatchUpdatesTo(adapter)函数实现刷新指定项,若是想作得更细,只刷新指定项中某个textView,imageView等也是能够,主要经过如下两个接口实现:this

DiffUtil.Callback的

public Object getChangePayload(int oldItemPosition, int newItemPosition)spa

RecyclerView.Adapter的

public void onBindViewHolder(VH holder, int position, List payloads)code

当一个item中包含多个view,好比item中有图片但我只想刷新某个textView,这种方式仍是能提升性能的,这里不细讲。

LivaData

LiveData是一个可被观察的数据持有类,与通常的Observer不一样的是,LiveData能意识到应用程序组件的生命周期变化,其优势主要有:

·  确保UI符合数据状态

LiveData遵循观察者模式。 当生命周期状态改变时,LiveData会向Observer发出通知。 您能够把更新UI的代码合并在这些Observer对象中。没必要去考虑致使数据变化的各个时机,每次数据有变化,Observer都会去更新UI。

·  没有内存泄漏

Observer会绑定具备生命周期的对象,并在这个绑定的对象被销毁后自行清理。

·  不会因中止Activity而发生崩溃

若是Observer的生命周期处于非活跃状态,例如在后退堆栈中的Activity,就不会收到任何LiveData事件的通知。

·  不须要手动处理生命周期

UI组件只须要去观察相关数据,不须要手动去中止或恢复观察。LiveData会进行自动管理这些事情,由于在观察时,它会感知到相应组件的生命周期变化。

·  始终保持最新的数据

若是一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据。 例如,后台Activity在返回到前台后当即收到最新数据。

·  正确应对配置更改

若是一个Activity或Fragment因为配置更改(如设备旋转)而从新建立,它会当即收到最新的可用数据。

您可使用单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享。LiveData对象一旦链接到系统服务,任何须要该资源的Observer都只需观察这个LiveData对象。

通常用法:

public classProductListFragmentextendsFragment {

…..

private voidsubscribeUi(ProductListViewModel viewModel) {// Update the list when the data changes

LiveData> liveData= viewModel.getProducts();

//第一个参数是LifecycleOwner接口的实现类(Activity,Fragment等)

//关联liveData与观察者,匿名的Observer有Fragment的引用,当liveData更新

//其实是liveData->通知Observer->通知FragmentliveData.observe(this, newObserver>() {@Overridepublic voidonChanged(@NullableList myProducts) {if(myProducts !=null) {mBinding.setIsLoading(false);mProductAdapter.setProductList(myProducts);}else{mBinding.setIsLoading(true);}

mBinding.executePendingBindings();}

});}

//在某个地方,好比网络上拉取到数据,执行

//viewModel.getProducts().setValue(….)便可通知Fragment更新

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值