Android mvvm使用流程
一.几种常见架构模式对比
1.MVC(Model-View-Controller)
MVC模式的优点在于模块化、可扩展性和可维护性,但缺点是控制器和视图之间的耦合度较高。
2.MVP(Model-View-Presenter)模式
Presenter同时持有Model和View对象,缺点是V层与P层还是有一定的耦合度
3.MVVM(Model-View-ViewModel)
ViewModel作为中间层,将数据从Model传递给View,
ViewModel 可以将数据与 UI 组件的生命周期进行绑定。
ViewModel 类提供了一种保存和管理界面相关数据的机制,并确保这些数据在配置更改(如设备旋转)时不会丢失或重新创建。
二.使用方法
1.model 层
getTestLiveData 返回LiveData提供 数据给ViewModel,ViewModel 及view层获取到LiveData即监听数据的变化。
创建model类
public class TestLiveDataRepositoryImpl { private static final String TAG = AppConstants.APP_TAG + "TestLiveDataRepositoryImpl"; private static volatile TestLiveDataRepositoryImpl mInstance; private MutableLiveData<String> mTestLiveData1 = new MutableLiveData<>(); private MutableLiveData<String> mTestLiveData2 = new MutableLiveData<>(); //在创建一个聚合类MediatorLiveData private MediatorLiveData<String> mMediatorLiveData = new MediatorLiveData<>(); private Handler mHandler = new Handler(); public TestLiveDataRepositoryImpl() { //分别把mTestLiveData1和mTestLiveData2合并到mediatorLiveData中,只要有一个变化都会触发mMediatorLiveData变化 mMediatorLiveData.addSource(mTestLiveData1, new Observer<String>() { @Override public void onChanged(String testLiveData1Str) { Log.i(TAG, "mMediatorLiveData.onChanged mTestLiveData1 testLiveData1Str:" + testLiveData1Str); mMediatorLiveData.postValue(testLiveData1Str); } }); mMediatorLiveData.addSource(mTestLiveData2, new Observer<String>() { @Override public void onChanged(String testLiveData2Str) { Log.i(TAG, "mMediatorLiveData.onChanged mTestLiveData2 testLiveData2Str:" + testLiveData2Str); mMediatorLiveData.postValue(testLiveData2Str); } }); } public static TestLiveDataRepositoryImpl getInstance() { if (mInstance == null) { synchronized (TestLiveDataRepositoryImpl.class) { if (mInstance == null) { mInstance = new TestLiveDataRepositoryImpl(); } } } return mInstance; } public LiveData<String> getTestLiveData() { // testDelaySendLiveData1(3); // testDelaySendLiveData2(6); return mMediatorLiveData; } //模拟数据1变化 private void testDelaySendLiveData1(int second) { Log.i(TAG, "testDelaySendLiveData1 11 second:" + second); mHandler.postDelayed(() -> { Log.i(TAG, "testDelaySendLiveData1 22 call setValue second:" + second); //如果当前在子线程中必须使用postValue mTestLiveData1.setValue("delay " + second + " seconds"); }, 1000 * second); } //模拟数据2变化 private void testDelaySendLiveData2(int second) { Log.i(TAG, "testDelaySendLiveData2 11 second:" + second); mHandler.postDelayed(() -> { Log.i(TAG, "testDelaySendLiveData2 22 call setValue second:" + second); //如果当前在子线程中必须使用postValue mTestLiveData2.setValue("delay " + second + " seconds"); }, 1000 * second); } /** * 模拟数据变化调用,可以通过点击按钮调用模拟触发 */ public void delaySetValue() { Log.i(TAG, "delaySetValue "); testDelaySendLiveData1(3); testDelaySendLiveData2(6); } }
2.ViewModel 层
2.1 创建ViewModel 类MyViewModel
public class MyViewModel extends ViewModel { private static final String TAG = "MyViewModel "; public int count = 0; public MyViewModel() { count = 0; Log.i(TAG, "MyViewModel() "); } public LiveData<String> getTestLiveData() { return TestLiveDataRepositoryImpl.getInstance().getTestLiveData(); } public void delaySetValue() { Log.i(TAG, "delaySetValue "); TestLiveDataRepositoryImpl.getInstance().delaySetValue(); } }
2.2 创建 ViewModelProvider.Factory 类
public class MyViewModelFactory implements ViewModelProvider.Factory { private static final String TAG = "MyViewModelFactory "; public MyViewModelFactory() { } @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { Log.i(TAG, "create() modelClass:" + modelClass); if (modelClass == MyViewModel.class) { return (T) new MyViewModel(); } return null; } }
3.创建view类UiTestActivity
ViewModelProvider初始化时如果不传递 ViewModelProvider.Factory,则ViewModelProvider内部会使用默认的 Factory,
如果配置修改比如修改语言,activity 被销毁,再次打开activity获取的还是销毁前mMyViewModel对象。
即销毁前count被设置了3,重新打开activity打印mMyViewModel.count还是3。
public class UiTestActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = AppConstants.APP_TAG + "UiTestActivity "; private Button mBtnOne; private final Handler mHandler = new Handler(); private MyViewModel mMyViewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_activity); //如果不传递 ViewModelProvider.Factory,则内部会使用默认的 Factory, //如果配置修改比如修改语言,activity 被销毁,再次打开activity获取的还是销毁前mMyViewModel对象。 //即销毁前count被设置了3,重新打开activity打印mMyViewModel.count还是3。 //mMyViewModel = new ViewModelProvider(this).get(MyViewModel.class); mMyViewModel = new ViewModelProvider(this, new MyViewModelFactory()).get(MyViewModel.class); final Observer<String> testObserver = new Observer<String>() { @Override public void onChanged(String testStr) { //更新ui Log.d(TAG, "testObserver.onChanged testStr:" + testStr); } }; Log.d(TAG, "onCreate ** UiTestActivity is mMyViewModel.count:" + mMyViewModel.count + " mMyViewModel:" + mMyViewModel); mMyViewModel.getTestLiveData().observe(this, testObserver); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.test_btn1: mMyViewModel.count++; Log.d(TAG, "test_btn1.onClick() mMyViewModel.count:" + mMyViewModel.count); //通过点击按钮模拟model数据变化 mMyViewModel.delaySetValue(); break; default: break; } } }
标签:Log,mvvm,流程,private,second,TAG,Android,mMyViewModel,public From: https://www.cnblogs.com/adamli/p/18342617