Android MVVM架构浅析封装

MVVM 架构相对于MVP来说其实思想上是一致的,只是MVP中的P层在MVVM中换成了ViewModel,所以MVVM的模块结构如下图(截图出自https://developer.android.google.cn/jetpack/guide)
Android MVVM架构浅析封装_第1张图片
这里面的LiveData 和Room 其实都是Google一直在推的JetPack 中的组件,更多的组件大家可以去https://developer.android.google.cn/jetpack 中查看

回到MVVM 在MVVM中使用ViewModel 和LiveData 要引入依赖,因为现在我们的项目一般都迁移到了AndroidX,所以就不需要单独进行引入了,而且AndroidX还引入了LifeCycle,可以很方便进行生命周期的管理,防止内存泄漏(如果要单独引入,可以这样)

dependencies {
    def lifecycle_version = "2.2.0"

    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    ...
}

依赖好了,我们最好再启用DataBinding ,这里我只使用DataBinding 的findViewById 功能,这也是官方一直推荐的,而且Butterknife现在已经停更了,官方说明中是这样说的This tool is now deprecated. Please switch to view binding. 所以我们没有理由不使用DataBinding
首先在build.gradle中的android{}启用

dataBinding {
        enabled = true
    }

然后将我们的布局最外层套一层layout,像这样



    
        
    

接下来我们开始封装MVVM,它其实是MVP的封装思想是一样的,所以这里我们如果熟知MVP,是非常好理解的,先贴下代码

public abstract  class BaseActivity<VM extends BaseViewModel,V extends ViewDataBinding> extends AppCompatActivity implements IBaseView {
     
    protected VM viewModel;
    protected V viewBinding;
    protected LoadingUtils loadingUtil;
    protected ToastUtils customToastUtils;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);
        viewBinding = DataBindingUtil.setContentView(this,setLayoutRes());

        initParam();
        //初始化ViewModel
        initViewModel();
        initView();
        initToolBar();

        initData();
        initViewObservable();

    }


    protected abstract void initView();

    protected abstract int setLayoutRes();


    private void initViewModel() {
     
        viewBinding.setLifecycleOwner(this);

        //获取ViewModel实例
        ViewModelProvider viewModelProvider = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()));
        //获取返回直接继承的父类(包含泛型参数)
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        if (parameterizedType != null){
     
            //
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();

            Class<VM> tClass = (Class<VM>) actualTypeArguments[0];

            viewModel = viewModelProvider.get(tClass);

            getLifecycle().addObserver(viewModel);

        }


    }
    private void initToolBar() {
     

    }

    @Override
    public void initParam() {
     
        loadingUtil = new LoadingUtils(this);
        customToastUtils = ToastUtils.getDefaultMaker().setGravity(Gravity.CENTER,0,0)
                .setDurationIsLong(true).setMode(ToastUtils.MODE.DARK);
    }

    @Override
    public void initData() {
     

    }

    @Override
    public void initViewObservable() {
     

    }

    @Override
    public void onContentReload() {
     

    }

    @Override
    protected void onDestroy() {
     
        super.onDestroy();

    }


}

在基类中,通过泛型,来将一些重复的代码进行封装,对于BaseModel,StateLiveData大家可以不用关心,这里主要针对一些Rxjava 发送的一些请求,在具体的ViewModel 中添加进来,并且在ViewModel 生命周期结束的时候进行清空,可以避免内存泄漏

public class BaseViewModel extends AndroidViewModel implements IBaseViewModel, Consumer<Disposable> {
     
    protected StateLiveData<Object> stateLiveData;

    private CompositeDisposable compositeDisposable;
    public BaseViewModel(@NonNull Application application) {
     
        super(application);
        compositeDisposable = new CompositeDisposable();
        stateLiveData = new StateLiveData<Object>();

    }



    public StateLiveData<Object> getStateLiveData() {
     
        return stateLiveData;
    }

    @Override
    public void onAny() {
     

    }

    @Override
    public void onCreate() {
     

    }

    @Override
    public void onDestroy() {
     

    }

    @Override
    public void onStart() {
     

    }

    @Override
    public void onStop() {
     

    }

    @Override
    public void onResume() {
     

    }

    @Override
    public void onPause() {
     

    }

    @Override
    public void accept(Disposable disposable) throws Exception {
     
        compositeDisposable.add(disposable);
    }

    @Override
    protected void onCleared() {
     
        super.onCleared();
        if (compositeDisposable != null && compositeDisposable.size() > 0){
     
            compositeDisposable.clear();
            compositeDisposable = null;
        }
    }
}

具体的ViewModel 中,就是进行网络请求和简单的数据处理,将结果通过LiveData型的数据传递给Activity或Fragment,

class HomeViewModel(application: Application) : BaseViewModel(application) {
     
    val liveData = MutableLiveData<HomeArticleListResponse>()
    val errorLiveData = MutableLiveData<String>()



    fun getHomeArticle(pageNum: Int) {
     
        stateLiveData.postLoading()
        AppRequest.get().getHomeArticalList(pageNum)
            .compose(RxUtils.observableToMain())
            //绑定当前VIewModel 的生命周期  ViewModel
            .doOnSubscribe(this)
            .subscribe(object : BaseObserver<HomeArticleListResponse>() {
     
                override fun onSuccess(baseResponse: BaseResponse<HomeArticleListResponse>) {
     
                    if (baseResponse.data == null) {
     
                        errorLiveData.postValue(ViewModelConst.SUCCESSNODATA)
                    } else {
     
                        liveData.postValue(baseResponse.data)
                    }
                    stateLiveData.postSuccess()
                }

                override fun onCodeError(baseResponse: BaseResponse<*>) {
     
                    errorLiveData.postValue(baseResponse.errorMsg)
                    stateLiveData.postError()
                }

                override fun onFailure(exception: ResponseCustomException) {
     
                    errorLiveData.postValue(exception.message)
                    stateLiveData.postError()
                }
            })

    }
}

在Activity中获取结果也很方便,从viewModel中拿到对应的LiveData,作数据的监听就可以了,LiveData 获取到数据会自动进行数据的填充,

 viewModel.liveData.observe(this,
            androidx.lifecycle.Observer<HomeArticleListResponse> {
     
                val datas = it.datas
                val curPage = it.curPage
                if (pageNum == 0) {
     
                    articleListAdapter!!.setNewData(datas)
                } else {
     
                    if (curPage >= it.pageCount) {
     
                        //没有页了
                        viewBinding.homeSmartRl.finishLoadMoreWithNoMoreData()
                    } else {
     
                        if (datas != null && datas.isNotEmpty()) {
     

                            articleListAdapter!!.addData(datas)
                        } else {
     
                            viewBinding.homeSmartRl.finishLoadMore(false)
                        }
                    }
                }
            })

以上就是MVVM的一些简单封装使用,大家可以结合项目实际再做加工,毕竟封装的习惯每个人都不一样,只要了解了思想,都只是一种形式。

你可能感兴趣的:(Android开发中的点滴记录,安卓,mvvm)