Android官方MVVM框架实现组件化之整体结构

一、google官方MVVM框架讲解

我前面对比了MVC和MVP《两张图看懂Android开发中MVC与MVP的区别》,可以相对于MVC我们的MVP是有多优越,但是Android开发现在已经开始流行了MVVM,前不久google官方发布了MVVM的正式库。官方的正式MVVM库主要包括下面四个:

其中只有ViewModel是MVVM结构中的一个组件,其他的三个都是辅助性质的。

lifecycles 就是处理UI界面的生命周期,在26版本以后的Support库中,AppCompatActivity和SupportActivity中都实现了LifecycleOwner,内部已经对UI界面的生命周期做了处理了。

LiveData是一个抽象类,我们可以存放UI页面需要的数据,就是把数据包装在LiveData中了,我们可以观测LiveData中的数据变化,但是LiveData是跟UI的生命周期关联的,当UI页面销毁了,LiveData的数据变化回调是不会执行的。

Room 就是一个sqlite数据持久化库,我们也可以使用别的ORM库。

二、MVVM架构优势

《两张图看懂Android开发中MVC与MVP的区别》 前面两张图真是了MVC和MVP的区别,我这里也来一张图看看MVVM:

看上图Model和View是不会发生关系的,ViewModel是把View和Model关联起来的加工厂:

MVVM优势总结:

1,View和Model双向绑定,一方的改变都会影响另一方,开发者不用再去手动修改UI的数据。额,互相自动的。

2,不需要findViewById也不需要butterknife,不需要拿到具体的View去设置数据绑定监听器等等,这些都可以用DataBinding完成。是不是很舒服?

3,View和Model的双向绑定是支持生命周期检测的,不会担心页面销毁了还有回调发生,这个由lifeCycle完成。

4,不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的View和Presenter接口。项目结构更加低耦合。

5,更低的耦合把各个模块分开开发,分开测试,可以分给不同的开发人员来完成。

三、MVVM组件化示例项目架构分析

下图是项目模块和工程之间的依赖关系:

下图是工程Android Studio中的目录结构:

3.1 各模块和彼此之间的关系解释:

lib_opensource :第三方build.gradle依赖,本项目主要有support、lifecycle、room、fresco、retrofit、okhttp、RxJava、ARouter这些。

libcoremodel: 存放MVVM中的Model和ViewModel两个模块,就是数据的处理和数据与UI页面的绑定。依赖libopensource库。

libcommon : 公共库,主要有各种base,各种ui组件,自定义组件,公用的Activity、公用的Fragment,和公用的utils等等。依赖libcoremodel库。

module_girls : 妹子功能模块,可以在library和application之间切换,自己可以是一个app也可以成为别的app的一个组件模块。组件化编译时为app,反之为module。

module_news : 新闻功能模块,可以在library和application之间切换,自己可以是一个app也可以成为别的app的一个组件模块。组件化编译时为app,反之为module。

appuniversal : 定制版本的app,组件化编译时 modulegirls和modulenews为app,所以不能把这两个作为module加进来编译,所以组件化编译时appuniversal要依赖libcommon库,反之就可以把 modulegirls和module_news作为module加进来编译。

appspecific : 定制版本的app,组件化编译时 modulegirls和modulenews为app,所以不能把这两个作为module加进来编译,所以组件化编译时appspecific要依赖libcommon库,反之就可以把 modulegirls和module_news作为module加进来编译。

3.2 ARouter串联各个模块

使用ARouter来跳转Activity和获取Fragment,记得看之前别人的组件化结构文章,一直都在纠结Fragment的获取问题,我想说的是有了ARouter来获取Fragment不是超级简单么?

ARouter典型应用

从外部URL映射到内部页面,以及参数传递与解析
跨模块页面跳转,模块间解耦
拦截跳转过程,处理登陆、埋点等逻辑
跨模块API调用,通过控制反转来做组件解耦
3.3 组件化编译和非组件化编译切换

我们在工程根目录下的gradle.properties文件中加入一个Boolean类型的变量,通过修改这个变量来识别编译模式:

每次更改“isModule”的值后,需要点击 "Sync Project" 按钮

isModule是“集成开发模式”和“组件开发模式”的切换开关

isModule=false
然后在 modulegirls和modulenews中的build.gradle文件中支持切换:

if (isModule.toBoolean()) {
//组件化编译时为application
apply plugin: ‘com.android.application‘
} else {
//非组件化编译时为library
apply plugin: ‘com.android.library‘
}

android {
compileSdkVersion build_versions.target_sdk
buildToolsVersion build_versions.build_tools

defaultConfig {
    minSdkVersion build_versions.min_sdk
    targetSdkVersion build_versions.target_sdk
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    //ARouter
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [moduleName: project.getName()]
        }
    }
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘
    }
}
dataBinding {
    enabled = true
}
lintOptions {
    abortOnError false
}
sourceSets {
    main {
        if (isModule.toBoolean()) {
            //组件化编译时为app,在对应的AndroidManifest文件中需要写ndroid.intent.action.MAIN入口Activity
            manifest.srcFile ‘src/main/module/AndroidManifest.xml‘
        } else {
            manifest.srcFile ‘src/main/AndroidManifest.xml‘
            //集成开发模式下排除debug文件夹中的所有Java文件
            java {
                //debug文件夹中放的是Application类,非组件化时不用有此类
                exclude ‘debug/**‘
            }
        }
    }
}

}

dependencies {
implementation fileTree(dir: ‘libs‘, include: [‘*.jar‘])
api project(‘:lib_coremodel‘)
api project(‘:lib_common‘)
implementation ‘com.android.support:support-v4:26.1.0‘
annotationProcessor deps.arouter.compiler
}
上面看到了组件化和非组件化编译会有不用的AndroidManifest文件,组件化时需要debug文件夹下面的application类,非组件化时排除此文件夹。

module下的AndroidManifest文件是组件化app编译时的,写了MAIN入口Activity

dubug下是组件化app编译时的Application类,初始化作为一个app运行时需要的资源等等。在非组件化编译在build.gradle文件中排除debug文件夹的所以东西。

3.4 最后预告:

后面会有一些列介绍在MVVM组件化过程中使用ARouter来跳转Activity和获取Fragment、DataBinding实现数据和UI的互相绑定、Rxjava2和Retrofit2动态数据获取,和AndroidViewModel的封装。

下面贴贴一个lib_coremodel库中我封装的AndroidViewModel,用泛型来确定数据类型,并且是动态URL获取数据:

package google.architecture.coremodel.viewmodel;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.databinding.ObservableField;
import android.support.annotation.NonNull;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;

import google.architecture.coremodel.datamodel.http.ApiClient;
import google.architecture.coremodel.datamodel.http.ApiConstants;
import google.architecture.coremodel.datamodel.http.service.DynamicApiService;
import google.architecture.coremodel.util.JsonUtil;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;

/**

  • Created by dxx on 2017/11/20.
    */

public class BaseViewModel<T> extends AndroidViewModel {

//生命周期观察的数据
private MutableLiveData<T>  liveObservableData = new MutableLiveData<>();
//UI使用可观察的数据 ObservableField是一个包装类
public ObservableField<T> uiObservableData = new ObservableField<>();

private final CompositeDisposable mDisposable = new CompositeDisposable();

private static final MutableLiveData ABSENT = new MutableLiveData();
{
    //noinspection unchecked
    ABSENT.setValue(null);
}

public BaseViewModel(@NonNull Application application, String fullUrl) {
    super(application);
    ApiClient.initService(ApiConstants.GankHost, DynamicApiService.class).getDynamicData(fullUrl).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<ResponseBody>() {
        @Override
        public void onSubscribe(Disposable d) {
            mDisposable.add(d);
        }

        @Override
        public void onNext(ResponseBody value) {
           if(null != value){
               try {
                   liveObservableData.setValue(JsonUtil.Str2JsonBean(value.string(), getTClass()));
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });
}

/**
 * LiveData支持了lifecycle生命周期检测
 * @return
 */
public LiveData<T> getLiveObservableData() {
    return liveObservableData;
}

/**
 * 当主动改变数据时重新设置被观察的数据
 * @param product
 */
public void setUiObservableData(T product) {
    this.uiObservableData.set(product);
}

public Class<T> getTClass(){
    Class<T> tClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    return tClass;
}

@Override
protected void onCleared() {
    super.onCleared();
    mDisposable.clear();
}

}

原文地址:http://blog.51cto.com/13807306/2130726

时间: 2024-11-05 22:00:55

Android官方MVVM框架实现组件化之整体结构的相关文章

Android 开发:由模块化到组件化(一)

模块化和组件化 模块化 组件化不是个新概念,其在各行各业都一直备受重视.至于组件化什么时候在软件工程领域提出已经无从考究了,不过呢可以确认的是组件化最早应用于服务端开发,后来在该思想的指导下,前端开发和移动端开发也产生各自的开发方式. 在了解组件化之前,先来回顾下模块化的定义 Modular programming is a software design technique that emphasizes separating the functionality of a program in

Android项目架构之业务组件化

前言: 从个人经历来说的话,从事APP开发这么多年来,所接触的APP的体积变得越来越大,业务的也变得越来越复杂,总来来说只有一句话:这是一个APP臃肿的时代!所以为了告别APP臃肿的时代,让我们进入一个U盘时代,每个业务模块都是一个具备独立运行的盘,插在哪里都可以完美运行,这就是推进业务组件的初衷也是一个美好的愿景. 需求背景: 随着公司的快速发展,版本不断的迭代,业务变得也越来越复杂,业务模块的数量有可能还会继续增加,而且每个模块的代码也会越来越多,这样下去势必影响开发效率,增加项目的维护成本

Android官方数据绑定框架DataBinding

一.Data Binding是什么? 2015年的Google IO大会上,Android 团队发布了一个数据绑定框架(Data Binding Library),官方原生支持 MVVM 模型.以后可以直接在 layout 布局 xml 文件中绑定数据了,无需再 findViewById 然后手工设置数据了.其语法和使用方式和 JSP 中的 EL 表达式非常类似. Data Binding Library 是一个 support 库,支持 Android 2.1+ 版本 (API level 7

全面介绍Android的MVVM框架 - 数据绑定

原文地址 MasteringAndroidDataBinding 本教程是跟着 Data Binding Guide 学习过程中得出的一些实践经验,同时修改了官方教程的一些错误,每一个知识点都有对应的源码,争取做到实践与理论相结合. Data Binding 解决了 Android UI 编程中的一个痛点,官方原生支持 MVVM 模型可以让我们在不改变既有代码框架的前提下,非常容易地使用这些新特性.其实在此之前,已经有些第三方的框架(RoboAndroid) 可以支持 MVVM 模型,无耐由于框

Android官方数据绑定框架DataBinding(一)

还记得在博客<高逼格UI-ASD(Android Support Design)>的开始曾经说过,Android最新推出了一个官方的数据绑定框架-Data Binding Library.现在github上也有很多三方的数据绑定框架,但是我们为什么要选择官方的呢?恩,答对了.就是因为是官方的,三方的东西说不定什么时候作者一步高兴就停止更新了,官方的就不一样了,我们可以看到它渐渐的稳定起来.好了废话不多说,从这篇博客开始,我们就来了解一下android最新给我们带来的数据绑定框架--Data B

TINY框架:组件化的J2EE开发框架

<ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op>

Android组件化

附:Android组件化和插件化开发 App组件化与业务拆分那些事 Android项目架构之业务组件化 Android组件化核心之路由实现

Android应用程序框架之无边界设计意图

Android的应用框架的外特性空间的描述在SDK文档有十分清楚的描述,Android应用的基本概念,组件生命周期等等有详细的描述.在外特性空间中,Android提供了Activity,Service,Broadcast receivers,Content Provider,Intent,task等概念,我在这里不讨论这些概念定义,因为SDK文档已经讲得够详细. 在阅读SDK文档和研究Activity这个概念时,我感觉到了在Android中若隐若现的Android自由无边界这个设计意图.Andr

Android--开发:由模块化到组件化

在Android SDK一文中,我们谈到模块化和组件化,现在我们来聊聊组件化开发背后的哪些事.最早是在广告SDK中应用组件化,但是同样适用于普通应用开发 以下高能,请做好心理准备,看不懂请发私信来交流.本文不推荐新手阅读,如果你刚接触Android开发不久,请立刻放弃阅读本文. 模块化和组件化 模块化 组件化不是个新概念,其在各行各业都一直备受重视.至于组件化什么时候在软件工程领域提出已经无从考究了,不过呢可以确认的是组件化最早应用于服务端开发,后来在该思想的指导下,前端开发和移动端开发也产生各