Google’s latest MVVM architecture, based on dataBinding, Lifecycle, RetroFIT2, RxJavA2, OKHTTP, Fresco.

Jane books blog: http://www.jianshu.com/p/c0988e7f31fd

UI diagram of the first page of the two customized apps:

app_universal app_specific
ActivityMain component, click will jump to different component libraryActivity throughARoyterGet different component librariesFragmentTo show

First, MVVM architecture advantages

The first two diagrams are really the difference between MVC and MVP. Here is another diagram for MVVM:

ViewModel is a processing factory for associating a View with a Model.

Summary of MVVM advantages:

  1. View and Model are bound in both directions, so changes in one affect the other, eliminating the need for developers to manually modify UI data. Well, it’s automatic.

  2. You don’t need findViewById, you don’t need a butterknife, you don’t need to get a specific View to set up a DataBinding listener, and so on. You can use DataBinding. Isn’t it comfortable?

  3. The bidirectional binding of the View and Model supports lifeCycle detection without worrying about the page being destroyed and the callback happening, which will be done by lifeCycle.

  4. It doesn’t have a lot of code in an Activity like MVC, and it doesn’t have a lot of View and Presenter interfaces like MVP. The project structure is less coupled.

  5. Lower coupling allows modules to be developed separately, tested separately, and distributed among different developers.

Ii. Architecture analysis of MVVM componentization example project

The following figure shows the dependencies between project modules and the project:

The following is the directory structure in project Android Studio:

3.1 Explanation of the relationship between modules and each other:

  • Lib_opensource: third-party build.gradle dependencies, including Support, Lifecycle, room, fresco, Retrofit, okHTTP, RxJava, ARouter, etc.

  • Lib_coremodel: holds the Model and ViewModel modules in MVVM, which are used to process data and bind data to UI pages. Rely on the lib_openSource library.

  • Lib_common: public library, including bases, UI components, custom components, public activities, public fragments, public utils, etc. Rely on the lib_coreModel library.

  • Module_girls: girl function module, which can switch between Library and Application, and can be an app itself or a component module of another app. Componentized compilation is APP, and vice versa.

  • Module_news: News function module, which can switch between Library and Application. It can be an app or a component module of another app. Componentized compilation is APP, and vice versa.

  • app_universal : Module_girls and module_news will be componentized as apps, so app_universal will rely on lib_common for componentized compilation. Instead, you can compile module_girls and module_news as modules.

  • app_specific : Module_girls and module_news will be componentized as apps, so app_specific will rely on lib_common for componentized compilation. Instead, you can compile module_girls and module_news as modules.

3.2 ARouter series the modules

Use ARouter to jump into activities and get fragments. I remember reading someone else’s article about componentized structures. I was always struggling with the problem of getting fragments.

ARouter typical application

  • Mapping from external urls to internal pages, and parameter passing and parsing
  • Page hopping across modules, decoupling between modules
  • Intercept jump process, processing logics such as login and buried point
  • Cross-module API calls do component decoupling through control inversion

3.3 Switching between componentized compilation and uncomponentized compilation

We add a Boolean variable to the gradle.properties file in the root directory of the project and modify this variable to recognize the compilation mode:

IsModule is a toggle switch between integrated development mode and Component development mode. IsModule =falseCopy the code

Then support switching in build.gradle files in module_girls and module_news:

If (isModule.toboolean ()) {// Component.toboolean (); 'com.android.application'} else {// Uncomponentized compile as library Apply plugin: 'com.android.library' } android { compileSdkVersion build_versions.target_sdk buildToolsVersion build_versions.build_tools defaultConfig { minSdkVersion build_versions.min_sdk targetSdkVersion 1 versionName build_versions. Target_sdk versionCode testInstrumentationRunner "1.0" "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 ()) {// Component-based compile for app, The corresponding AndroidManifest file need to write a ndroid intent. Action. The MAIN entrance to the Activity manifest. The srcFile 'SRC/MAIN/module/AndroidManifest. XML'} Else {manifest. SrcFile 'SRC/main/AndroidManifest. XML' / / integrated development mode to rule out all the Java files in the debug folder Java {/ / debug folder into the Application class, 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 piler} deps.arouter.comCopy the code

We saw above that componentized and uncomponentized compilation may not be usedAndroidManifestFiles are required for componentizationdebugUnder the folderapplicationClass, which excludes this folder when uncomponentized.

  • moduleUnder theAndroidManifestThis file is componentized app compile time, writeMAINThe entranceActivity
  • dubugThe following is componentized app compile timeApplicationClass, initialized as oneappResources required at runtime, and so on. In uncomponentized compilation inbuild.gradleExclude from filedebugAll the stuff in the folder.