首页 > 其他分享 >Android mvvm使用流程

Android mvvm使用流程

时间:2024-08-05 09:27:30浏览次数:11  
标签:Log mvvm 流程 private second TAG Android mMyViewModel public

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

相关文章

  • 自定义导航栏兼容ios和android
    <template>  <view class="content">    <!--距离顶部的距离刚好留出状态栏即可即statusBarHeight-->    <view class="topNav" :style="{height:navHeight+'px',paddingTop:statusBarHeight+'px'}">      <......
  • Java流程控制语句结构--分支结构
    目录if语句switch语句三元运算符(条件运算符)总结Java中的分支结构是程序设计中用于根据条件选择不同执行路径的重要机制。它允许程序在运行时根据特定条件来决定执行哪一部分代码。Java中的分支结构主要包括以下几种:if语句基本形式:if(条件表达式){语句块;}如果条件表达式......
  • Java流程控制语句结构--循环结构
    目录while循环do…while循环for循环三种循环的死循环形式while循环while是最基本的循环,它的结构为:while(布尔表达式(判断条件)){//循环内容}只要布尔表达式为true,循环就会一直执行下去。do…while循环对于while语句而言,如果不满足条件,则不能进入循环。但有时候我......
  • Java流程控制04:循环结构
    顺序结构的程序语句只能被执行一次。如果您想要同样的操作执行多次,就需要使用循环结构。Java中有三种主要的循环结构:while循环do…while循环for循环1.while循环while是最基本的循环,它的结构为:while(布尔表达式){//循环内容}只要布尔表达式为true,循环就会一......
  • Java流程控制05:break & continue
    1.break关键字break主要用在循环语句或者switch语句中,用来跳出整个语句块。break跳出最里层的循环,并且继续执行该循环下面的语句。【演示:跳出循环】publicstaticvoidmain(String[]args){ inti=0; while(i<100){ i++; System.out.println(i); if(i==......
  • Java流程控制03:选择结构
    1.if单选择结构我们很多时候需要去判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用if语句来表示:if(布尔表达式){ //如果布尔表达式为true将执行的语句}意义:if语句对条件表达式进行一次测试,若测试为真,则执行下面的语句,否则跳过该语句。比如我们来接收一个......
  • Java流程控制01:用户交互Scanner
    1.Scanner对象Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。下面是创建Scanner对象的基本语法:Scanners=newScanner(System.in);接下来演示一个最简单的数据输入,并通过Scanne......
  • Java流程控制02:顺序结构
    JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。顺序结构是最简单的算法结构。语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构。顺序结构在程序流程图中的体现就是......
  • Android ImageProxy 到 byteArray 并通过套接字发送
    我正在尝试将ImageProxy转换为byteArray,以通过套接字将其发送到python服务器。我正在使用Camerax,这是我的图像分析:mageAnalysisimageAnalysis=newImageAnalysis.Builder().setTargetResolution(newSize(720,640))......
  • 1388、STM32单片机心率(脉搏)MAX30102血氧体温检测阈值报警无线蓝牙远程(程序+原理图+
    毕设帮助、开题指导、技术解答(有偿)见文未 目录方案选择单片机的选择显示器选择方案一、设计功能二、实物图三、原理图四、程序源码五、PCB图六、proteus仿真程序流程图:原理图文字讲解:参考论文:资料包括:需要完整的资料可以点击下面的名片加下我,找我要资源压缩......