1. The background

In the past, the company has always used the MVP framework for projects. A few months ago, I personally developed an MVP version of App based on hongshen WanAndroid API. The deepest feeling in the process of using MVP is that the development efficiency is extremely low, with a lot of interfaces written and few reusable ones. At the beginning of this year, I learned about MVVM in Jetpack mode. With the support of LiveData, ViewModel and DataBinDing, I realized one-way dependency and DataBinDing. The amount of code was greatly reduced, and the stability of the project was also improved according to the features of Jetpack.

For a deeper understanding of the various components in Jetpack, I recently implemented another version of WanAndroid based on the Jetpack MVVM. Compared to the last version of the MVP added a night mode and music player, player interface modeled after netease Cloud Music. App also uses a lot of attribute animation to make the interface simple but not simple. Let’s look at it first

About the player currently only supports reading local music, if you want to experience can download a few songs in advance

Attach github:github.com/zskingking/ first…

2. Application technology

MVVM is used as the basic framework. Lifecycle, ViewModel, LiveData, DataBinDing, Navigation and Room are selected as Jetpack components.

Based on Navigation, the project is implemented by single Activity and multiple fragments. Using this mode gives me the most intuitive feeling that it is fast. For example, clicking search to enter the interface of search, it is impossible to be so coherent among multiple activities.

The entire project uses Kotlin language, and a large number of extension functions are written by using coroutines.

I define the responsibilities of each module as follows:

Model

Corresponding to the project Repository, do data requests and business logic. Many people write business logic in the VM layer, but I personally think it is more appropriate to write it in the Model layer, because the data is closely related to the business logic itself. When the data is obtained, the business logic is processed in time, and finally the data is sent to the View layer through the LiveData injected by the ViewModel. In this layer, I also encapsulated coroutines and uniformly captured and handled error messages. The code looks something like this:

/** * Error method */ TypeAlias Error =suspend (e: ApiException) -> Unit

/**
 * des 基础数据层
 * @date 2020/5/18
 * @author zs
 *
 * @param coroutineScope 注入viewModel的coroutineScope用于协程管理
 * @param errorLiveData 业务出错或者爆发异常,由errorLiveData通知视图层去处理
 */
open class BaseRepository(
    private val coroutineScope: CoroutineScope,
    private val errorLiveData: MutableLiveData<ApiException>
) {

    /**
     * 对协程进行封装,统一处理错误信息
     *
     * @param block   执行中
     * @param success 执行成功
     */
    protected fun <T> launch(
        block: suspend () -> T
        , success: suspend (T) -> Unit
        , error:Error? = null): Job {
        returncoroutineScope.launch { runCatching { withContext(Dispatchers.IO) { block() } }.onSuccess { success(it) }.onFailure { it.printStackTrace() getApiException(it).apply { error? .invoke(this) toast(errorMessage) // ErrorLiveData.value = this}}}} /** * Catch exception message */ private fun getApiException(e: Throwable): ApiException { ... . }}Copy the code

ViewModel

Encapsulation based on the ViewModel in Jetpack. (Note: Jetpack ViewModel has nothing to do with MVVM ViewModel, so don’t confuse the two.) The responsibilities of the VM layer in the project are simple, through internal data storage with LiveData and DataBinding with DataBinding.

View

Try to do only UI rendering. Different from MVP, View is bound to data through DataBinding, Activity or Fragment is very light only focus on life cycle management, data rendering is basically all realized by DataBinding+BindAdapter.

The package of MVVM template classes can be viewed under package com.zs.base_library.base(package name).

The network layer

The network layer continues to use the OkHttp Retrofit and encapsulates the Retrofit multi-apiservice and multi-domain. Coroutines encapsulated in Repository are used beautifully.

The database

The project history is maintained in the local database, for which Room in Jetpack is used.

Subject switch

The nighttime switching provided by Android native seems to be API versioning, so it’s useless. I personally maintain two sets of themes locally, which can be dynamically switched. Currently, there are two sets of themes: day and night

3. About comments

Last year, my Leader forced me to develop the habit of writing comments, and my personal requirements for writing comments are getting higher and higher.

A large number of design patterns are applied in the project. I will explain each design pattern in combination with the scene at that time. For example, an interface in the player, I will write comments like this:

/** * All des specific players must implement this interface so that PlayManager does not rely on any * specific audio Player implementation for two reasons ** 1.PlayManager contains business information. Player should not be coupled with business information, otherwise every change will affect the business * * 2. In accordance with the open and closed principle, if the Player needs to be replaced, it will inevitably involve the business in PlayManager, thus causing unnecessary trouble * If the programming is based on the IPlayer interface, it is necessary to expand a Player, which is called open for extension and closed for modification * * @author Zs * @data 2020-06-23 */ interface IPlayer { .... . } /** * DES audio management * through the singleton pattern, hosting the audio state and information, and as the only trusted source * through the observer pattern to distribute the state * is actually a proxy, the target object Player isolated from the caller, and the internal implementation of the observer registration and notification * @author zs * @data 2020/6/25 */ class PlayerManager private constructor() : IPlayerStatus { .... . }Copy the code
  • About the design of the player I think there are still some places worth sharing with you, I will write a separate article to analyze.

Write in the last

It’s hard to see any ambiguous code in this project. Jetpack and Kotlin are inevitable, since they can’t resist an unpleasant hug. Function has been completed 90%, the code is also in continuous optimization, welcome to pay attention to, download the source code, let us learn together, common progress.

Point a "like" you are the second most handsome person in the world, give a star you can surpass me to become the first handsome ~ _ ~

The enclosed github:github.com/zskingking/ again… If you think it will help you, please give a star