Android mvvm使用流程

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);
    }
}
View Code
复制代码

 

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。

复制代码
 1 public class UiTestActivity extends AppCompatActivity implements View.OnClickListener {
 2     private static final String TAG = AppConstants.APP_TAG + "UiTestActivity ";
 3     private Button mBtnOne;
 4     private final Handler mHandler = new Handler();
 5     private MyViewModel mMyViewModel;
 6  
 7     @Override
 8     protected void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.test_activity);
11  
12         //如果不传递 ViewModelProvider.Factory,则内部会使用默认的 Factory,
13         //如果配置修改比如修改语言,activity 被销毁,再次打开activity获取的还是销毁前mMyViewModel对象。
14         //即销毁前count被设置了3,重新打开activity打印mMyViewModel.count还是3。
15         //mMyViewModel = new ViewModelProvider(this).get(MyViewModel.class);
16  
17         mMyViewModel = new ViewModelProvider(this, new MyViewModelFactory()).get(MyViewModel.class);
18  
19         final Observer<String> testObserver = new Observer<String>() {
20             @Override
21             public void onChanged(String testStr) {
22                 //更新ui
23                 Log.d(TAG, "testObserver.onChanged testStr:" + testStr);
24             }
25         };
26         Log.d(TAG, "onCreate ** UiTestActivity is mMyViewModel.count:" + mMyViewModel.count
27                 + " mMyViewModel:" + mMyViewModel);
28         mMyViewModel.getTestLiveData().observe(this, testObserver);
29     }
30  
31     @Override
32     protected void onStop() {
33         super.onStop();
34         Log.d(TAG, "onStop");
35     }
36     @Override
37     protected void onDestroy() {
38         super.onDestroy();
39         Log.d(TAG, "onDestroy");
40     }
41  
42     @Override
43     public void onClick(View v) {
44         switch (v.getId()) {
45             case R.id.test_btn1:
46                 mMyViewModel.count++;
47                 Log.d(TAG, "test_btn1.onClick() mMyViewModel.count:" + mMyViewModel.count);
48                 //通过点击按钮模拟model数据变化
49                 mMyViewModel.delaySetValue();
50                 break;
51             default:
52                 break;
53         }
54     }
55 }    
View Code
复制代码

 

posted @   adam.li  阅读(167)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示