Introduction to the

After several years of development, I have been looking for a reasonable and easy to use development mode in Android, from MVC to MVP, and now MVVM, with Jetpack, Kotlin and coroutines, and the Rx series, I think the Android development paradigm has matured, and with the dynamic introduction of code provided by AS and Gradle, it is possible to encapsulate a development framework and provide AS much customization AS possible. Based on the basic development paradigm, the content of the framework is determined by configuration files.

Before we get started, let’s take a look at one of Google’s recommended architecture diagrams:

This is a diagram of MVVM architecture, divided into View, ViewModel, Model, three layers, there are clear call boundaries between layers, should avoid cross-layer call as much as possible, but the flexibility of code is very high, you can hardly completely avoid team members developing code that does not meet the framework standards. Once a member has an incomplete understanding of the framework, he or she will most likely choose a familiar implementation under the pressure of delivery time.

For example, you expect him to use Glide to load pictures, but because he’s been using Fresco, he might accidentally introduce it to you, but it’s very cheap to learn Glide, especially if it’s packaged. But that’s what people do. They go with what they know.

So in the team, should be a training of members, and supervise and urge members to learn and framework of knowledge, and actively found and reported problems, and continuous improvement framework, rather than a word like refactoring down the whole architecture, have to say “refactoring” was also the couple often ask the question, is not to say must say refactoring, However, most of the time, it is because he does not understand the framework, so he attacks the framework and tries to change it into something he is familiar with. At this time, the team leader should guide him correctly.

Above all, maintain a framework of cost is pretty big, need to form the corresponding document, video, and organize the training and so on, but the benefits are obvious, and framework of the unification standard, let each member became the spare tire, as long as you have needs, can quick learning, focus on business logic, improve members of the alternative, There will be no one in charge of the business because of the resignation of one person.

Ok, let’s look at how to create such a basic framework.

Desired goals

Let’s start by setting goals and clarifying our expectations for the framework. After sorting out, I think the objectives of the framework are as follows:

1. Basic framework paradigm

MVVM mode is used. The framework encapsulates basic functionality, making it easier to call layers, reducing boilerplate code, and making it easier to get started. For essential boilerplate code, you can quickly generate it through File Templates and Live Templates of AS, or even better, write an AS plug-in.

2. Unified third-party libraries

The use of libraries should be encapsulated as much as possible to avoid the introduction of duplicate libraries. Try to use official ones.

3. Customize as much as possible to reduce the package size

For some small projects or unwanted third-party libraries in the project, you can reduce the package size by removing the specified libraries through the configuration file. Even for some functions, make them customizable and avoid unnecessary instance creation.

4. Unified framework maintenance, convenient update.

The use of Git submodule function, the introduction of the framework of the source, do not use the way of remote repository, because the remote repository every update to update the version, too troublesome, inflexible. If your code is to be delivered, such as outsourced, you can eventually clear the framework’s.git directory and clean up the framework before delivering it, so that you don’t deliver code that customers don’t want, and also make a reservation about the framework. Team members work together to continuously optimize the functionality of the framework, and review updates and code merges.

View The View layer, or V layer for short

In Android, the View layer has activities/fragments and corresponding XML files.

For layout suggestions, the priority is to use ConstraintLayout, but if it is obviously LinearLayout, use LinearLayout, simple list use ListView, simple grid use GridView, complex use RecyclerView.

Drop-down refresh tensile loading on priority with scwang90 / SmartRefreshLayout, if only the drop-down refresh, adopt SwipeRefreshLayout.

The view layer will encapsulate BaseActivity/BaseFragment, hold the ViewModel and ViewDataBinding instance, so users can operation flow to the VM layer.

Asynchrony can be initiated at the V layer using lifecycleScope or lifecycle. CoroutineScope to make asynchrony follow the lifecycle and cancel the coroutine at the end of the lifecycle.

ViewModel Business logic layer, VM layer for short

In Android, the VM layer is made up of classes that inherit from the ViewModel or AndroidViewModel. The VM layer holds the Repository instance and can request data from the Repository. So how does the data flow to the V layer? The first thing to be clear about is that it is critical that the VM layer never hold an instance of the V layer, otherwise it will cause a memory leak. So how do you stream data without holding layer V instances?

The answer is to stream data back to tier V via LiveData or DataBinding. There are only two ways to do it.

In addition, with Lifecycles, the VM can sense the lifecycle of the V layer, which is the same as the LIFECYCLE of the V layer, which is also the point of encapsulation. But the onCleared method does not call back until V is completely destroyed.

Making asynchronous or Repository calls at the VM layer, using viewModelScope life-cycle aware coroutines instead of Rx, and automatically removing coroutines when interface destruction occurs, provides good performance. Or use liveData coroutines, which are automatically executed when liveData is activated, and will be automatically executed the next time it is activated if it is cancelled before completion.

Much of the interaction between the VM and V layers can be achieved through DataBinding, a DataBinding library from Google that should be used whenever possible. Of course, you can write the code in the V layer if you don’t have to, but DataBinding can minimize boilerplate code and should be required by the default framework.

The VM layer and V layer can encapsulate some common functions, such as loading dialog boxes, start and end interfaces, etc. It should also be considered that some interfaces do not need these functions, so it should also provide an interface to disable these functions to avoid unnecessary instance creation.

Model data layer, referred to as M layer

The main representations are Repository, Retrofit2 for requesting networks, Gson for parsing JSON, and Room for storing local data.

Access to networks, databases, files, etc., can use coroutines to achieve asynchronous.

Typically, Repository holds multiple data instances, such as network data instances and local data instances, but the exposed interface provides a data source that is insensitive to the user, i.e. the VM or V layer does not care about the data source and is controlled by the M layer.

In Google’s architecture guide, it is recommended to use Room as a single data source, that is, the user obtains all the data through Room, and using the features of Room, M layer operation of Room will automatically respond to the user’s latest changes.

Before requesting network data, local data is often used to prevent a blank screen, and then the network data is refreshed after the request is successful.

Jetpack must have a library

basis

  • AndroidX
  • AppCompat
  • MultiDex
  • Fragment

architecture

  • DataBinding
  • Lifecycles
  • LiveData
  • ViewModel

Optional libraries for Jetpack

  • Benchmark

  • Security

  • Navigation

  • Room

  • Paging

  • WorkManager

  • CameraX

  • DownloadManager

  • Notifications

  • Permissions

  • Preference

  • Animation

  • Palette

Other required libraries

  • ConstraintLayout
  • Kotlin
  • Kotlin-ktx

Other optional libraries

  • RecyclerView
  • material
  • swiperefreshlayout
  • viewPager2
  • Retrofit2, retrofit2RxJava2
  • glide
  • Gson, gsonConverter
  • RxJava2, rxKotlin
  • debugDB
  • leakCanary2
  • bindingAdapter
  • livePermissions
  • All kinds of KTX

Various optional support libraries

  • GridLayout
  • CardView
  • .

conclusion

To summarize, I open source the MVMARchitecture framework on Github, partly inspired by MVVMHabit and MVVMLin.

MVVMArchitecture main code is written by Kotlin, part of the tool class code using Java, for the content of the framework, greatly increased the customization function, try to achieve global configurable and configurable separately, see Github Wiki, the follow-up will continue to optimize and improve, Welcome fork, Star, issue.