JetPack组件 ViewModel+LiveData

一直以来,Android开发都充斥了大量的不规范的操作和重复代码,比如生命周期的管理,开发过程的重复,项目架构的选择等等。谷歌IO大会上,Google官方向推出了 Jetpack,旨在让开发者们能够更好,更快,更规范地开发出优质应用。

  • lifecycle
  • DataBinding
  • Navigation
  • Room
  • WorkManger
  • Paging

1. 作用

  1. 用以解决的痛点
  • 瞬态数据丢失
  • 异步调用内存泄漏
  • 类膨胀提高维护难度和测试难度
  1. viewModel是什么?
  • 它是介于View(视图)和Model(数据模型)之间的桥梁
  • 使视图和数据能够分离,也能保持通信

官方解释:ViewModel类是被设计用来以可感知生命周期的方式存储和管理 UI 相关数据,ViewModel中数据会一直存活即使 activity configuration发生变化,比如横竖屏切换的时候。

2. 使用

1.gradle依赖
//引入AndroidX吧,替换掉support包
implementation 'androidx.appcompat:appcompat:1.0.2'

def lifecycle_version = "2.0.0"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
2. ViewModel 简单应用
public class MyViewModel extends ViewModel {
     public int number;
}
public class MainActivity extends FragmentActivity {

   private TextView mTextView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       mTextView = findViewById(R.id.tv_content);

       //构建ViewModel实例
       MyViewModel viewModel = new ViewModelProviders(this,new ViewModelProvider
       .AndroidViewModelFactory(getApplication())).get(MyViewModel.class);

       mTextView.setText(String.valueOf(viewModel.number))
    
       findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               //点击按钮  更新number数据
               mTextView.setText(String.valueOf(++viewModel.number));
           }
       });
   }
}

编译后,以上在屏幕旋转之后数据任然存在不会丢失,是应为ViewModel的特性可以让它独立于配置变化。
注意:

  • 不要向ViewModel 中传入Context,会导致内存泄漏。
  • 如果必须使用Context,使用AndoridViewModel中的Application。
3. 使用ViewModel + LiveData 在 ViewModel中数据变化时通知页面

LiveData的优势

  • 确保界面符合数据状态
  • 不会反生内存泄漏
  • 不会因Activity 停止而导致崩溃
  • 不再需要手动处理生命周期
  • 数据始终保持最新状态
  • 适当的配置更改
  • 共享资源
public class MyViewModel extends ViewModel {
     public final MutableLiveData currentSecond = new MutableLiveData<>();
     public MutableLiveData getCurrentSecond(){
           if(currentSecond==null){
                  currentSecond = new MutableLiveData<>();
                  currentSecond.setValue(0);
            }
            returen currentSecond;
     }
}
public class MainActivity extends FragmentActivity {

    private TextView mTextView;
    private  MyViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = findViewById(R.id.tv_content);

        //构建ViewModel实例
        viewModel = new ViewModelProviders(this,new ViewModelProvider
        .AndroidViewModelFactory(getApplication())).get(MyViewModel.class);

        mTextView.setText(String.valueOf(viewModel.getCurrentSecond().getValue()));
     
        //  viewModel 中的数据变化会动态回调 
        viewModel.getCurrentSecond().observe(this,new Observer(){
                @Override
                  public void onChange(Integer data){
                      mTextView.setText(String.valueOf(data));
                  }
        });
        startTime(); 
    }

     private void startTime(){
           new Timer().schedule(new TimerTask(){
                 @Override
                  public void run(){
                     Integer value =  viewModel.getCurrentSecond().getValue();
                      // 非UI线程 postValue、UI线程 setValue
                     viewModel.getCurrentSecond().postValue(value+1);
                  }
           },1000,1000);
     }
}
4. 使用ViewModel + LiveData 实现Fragment间通信
public class SharedViewModel extends ViewModel {
    private final MutableLiveData selected = new MutableLiveData();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData getSelected() {
        return selected;
    }
}
public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
          // 实现通信的重点是 使用 getActivity()
        model = new ViewModelProviders(getActivity(),new ViewModelProvider
        .AndroidViewModelFactory(getApplication())).get(SharedViewModel.class);
      
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
          // 实现通信的重点是 使用 getActivity()
        SharedViewModel model = new ViewModelProviders(getActivity(),new ViewModelProvider
        .AndroidViewModelFactory(getApplication())).get(SharedViewModel.class);

        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}

你可能感兴趣的:(JetPack组件 ViewModel+LiveData)