Android架构组件(三)——ViewModel

Android架构组件(三)——ViewModel

上一篇文章讲到了Android架构组件之LiveData(Android架构组件(二)——LiveData),现在我们再来看看另一个成员ViewModel。

ViewModel是什么?

 ViewModel,从字面上理解的话,我们也能想到它肯定是跟视图(View)以及数据(Model)相关的。正像它字面意思一样,它是负责准备和管理和UI组件(Fragment/Activity)相关的数据类,也就是说ViewModel是用来管理UI相关的数据的。同时ViewModel还可以用来负责UI组件间的通信,这一点后面我们会有例子说明。

为什么需要ViewModel?

 在看过前面两篇介绍LifecycleLiveData的内容后,这个问题的基本就不用回答了。既然ViewModel是用来管理和UI组件有关的数据的,而LiveData又是这些数据的持有类,所以在使用LiveData的时候,就自然想到要使用ViewModel了。另外从ViewModel的定义,我们也能看到ViewModel还可以用于UI组件间的通信,回想下当初面试官问你Fragment之间怎么通信的问题,掌握ViewModel后就多了一种高逼格的回答了。

ViewModel基本使用

 前面在讲解LiveData时,我们已经使用了ViewModel,所以它的基本使用,在这里就不在赘述了,忘了的同学可以重新去翻一翻Android架构组件(二)——LiveData。我们主要看下ViewModel的生命周期,以及它用于组件间通信的使用。

ViewModel生命周期

 我们看看ViewModel的生命周期,在官方文档中,用下面这张图来描述ViewModel的生命周期。

 上图是用Activity作为例子,左侧表示Activity的生命周期状态,右侧绿色部分表示ViewModel的生命周期范围。当屏幕旋转的时候,Activity会被recreate,Activity会经过几个生命周期方法,但是这个时候ViewModel还是之前的对象,并没有被重新创建,只有当Activity的finish()方法被调用时,ViewModel.onCleared()方法会被调用,对象才会被销毁。这张图很好的描述了是当Activity被recreate时,ViewModel的生命周期。

  另外,有个注意的地方:在ViewModel中不要持有Activity的引用。为什么要注意这一点呢?从上面的图我们看到,当Activity被recreate时,ViewModel对象并没有被销毁,如果Model持有Activity的引用时就可能会导致内存泄漏。那如果你要使用到Context对象怎么办呢,那就使用ViewModel的子类AndroidViewModel吧。

用于组件间通信

  下面我们看下ViewModel用于Fragment之间通信的例子。

/**
 * Created by shymanzhu on 2017/12/26.
 */

public class CommunicateViewModel extends ViewModel {
   
    private static final String TAG = "CommunicateViewModel";
    private MutableLiveData<String> mNameLiveData;

    public LiveData<String> getName(){
   
        if (mNameLiveData == null) {
   
            mNameLiveData = new MutableLiveData<>();
        }
        return mNameLiveData;
    }

    public void setName(String name){
   
        if (mNameLiveData != null) {
   
            Log.d(TAG, "setName: " + name);
            mNameLiveData.setValue(name);
        }
    }

    @Override
    protected void onCleared() {
   
        super.onCleared();
        mNameLiveData = null;
    }
}
/**
 * Created by shymanzhu on 2017/12/26.
 */

public class FragmentOne extends Fragment {
   
    private CommunicateViewModel mCommunicateViewModel;

    public static FragmentOne getInstance(){
   
        return new FragmentOne();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        mCommunicateViewModel = ViewModelProviders.of(getActivity()).get(CommunicateViewModel.class);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
   
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @OnClick(R.id.btn_set_name)
    void onViewClicked(View v){
   
        switch (v.getId()){
   
            case R.id.btn_set_name:
                mCommunicateViewModel.setName("Jane");
                break;
        }
    }
}
/**
 * Created by shymanzhu on 2017/12/26.
 */

public class FragmentTwo extends 
  • 22
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值