ViewModel

ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。

原理图

Android ViewModel postValue 接收不到_数据

  1. 创建一个继承viewModel的类
public class MyViewModel extends ViewModel {
	// 需要保存的数据
    int count = 0;
    
}
  1. 为Activity添加一个ViewModel的成员,并且实例化
public class MainActivity extends AppCompatActivity {

	private MyViewModel myViewModel;

	publid void onCreate(){

		myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
}
}

在这之前先添加上依赖

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
  1. 使用ViewModelProvider创建的ViewModel能保证是同一个,即使Activity被销毁再创建也是,这样就能保存下很多数据。
  2. 像ViewModel传递初始参数
    如果ViewModel构造参数函数需要向ViewModel传递数据的话,就需要借助到ViewModelProvider.Factory,下面看一个例子
public class MainViewModelFactory implements ViewModelProvider.Factory {

    private int count;

    public MainViewModelFactory(int count) {
        this.count = count;
    }

    @Override
    public <T extends ViewModel> T create( Class<T> modelClass) {
    	// 这里的MainViewModel也是一个ViewModel,和上面不是同一个
        return (T) new MainViewModel(count);
    }
}

创建ViewModel实例时使用

mainViewModel = new ViewModelProvider(this,new MainViewModelFactory(num)).get(MainViewModel.class);

LiveData

LiveData是JetPack提供的一种响应式编程组件,它可以包含任意类型的数据,并在数据发生变化时通知给活跃状态的观察者(比如Activity处于Start或者Resume状态),在ACtivity销毁时及时释放引用(熟悉吗?想一想怎么实现的),它特别适合和ViewModel结合使用(实例演示)。

public class MainViewModel extends ViewModel {
    // LiveData 成员
    public MutableLiveData<Integer> counter=new MutableLiveData<>();

    public MainViewModel(int count){
        counter.setValue(count);
    }

    void addOne(){
        counter.setValue(counter.getValue()+1);
    }

    int getCount(){
        return counter.getValue();
    }
}

我实例化了一个MutableLiveData的成员,将其泛型指定为int类型,LiveData有三个成员函数setValue(), getValue(), postValue(), 其中在其他线程中传递数据一定要用 postValue()而不能用setValue()。同样我们在Activity中初始化

mainViewModel = new ViewModelProvider(this,new MainViewModelFactory(num)).get(MainViewModel.class);

为LiveData设置好数据变化时的回调函数

mainViewModel.counter.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                textView.setText(String.valueOf(integer));
            }
        });

数据变化时更新UI,可以使用handler测试一下,延迟几秒后更新value,UI也会被更新。

Lifecycles

概述
它是一个生命周期感知型组件,当被观察的组件的生命周期改变时可以执行操作来进行响应。简单的来说,可以通过它来监测如Activity,Fragment等具有生命周期的组件,并做出响应,从而依赖组件的代码从生命周期方法移入组件本身中,便于维护。
lifecycle中两个角色

  • LifeCycleOwner(生命周期拥有者),如Activity,Fragment,Service等
  • LifeCycleObserver(生命周期观察者),任何自定义类。

使用场景

  • 自定义View需要在Activity的onResume,onStop 或者其他状态下,进行动画显示数据加载保存等操作。(后面有演示)
  • 某些框架需要追踪Activity的生命周期变化,做出一些操作,比如之前培训的换肤框架,在Activity创建时进行换肤。
  • MVP框架中,在Activity的不同生命周期可能需要调用p中的某些方法,如果通过lifecycle联系起来,就可以减少Activity这个主动调用的过程,p中的方法会自动感知并调用,减少Activity的代码量。
public class MyObserver implements LifecycleObserver {

    private Lifecycle lifecycle;

    public MyObserver(Lifecycle lifecycle) {
        this.lifecycle = lifecycle;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreated(){
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(){
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(){
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause() {
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(){
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestory(){
        Log.d("lifecycle",lifecycle.getCurrentState().toString());
    }
}

在Activity中

getLifecycle().addObserver(new MyObserver(this.getLifecycle()));

这里为什么要把Activity本LifeCycle对象传递进去呢?因为获得Lifecycle对象后,就可以随时调用它的getCurrentState()方法获得其状态了。