Lazy must-have Jetpack MVVM framework

Table of contents

renderings

project dependencies

Introduction

The three-party library used by the project and its simple examples and materials

Introduction to the use of network requests

Introduction to the use of Google Jetpack framework

common problem

github address


Android Jetpack MVVM framework development, based on AndroidX development, fool-like use, suitable for all projects

Google Android Team Jetpack view model: 

renderings

project dependencies

allprojects {
   repositories {
	 maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
  implementation 'com.github.cl-6666:mvvm-framework:v2.1.0'
}

Introduction

The three-party library used by the project and its simple examples and materials

Introduction to the use of network requests

Introduction to the use of network logs


api function support list Whether to support
Support data formatted output of http request and response support
When the request is Post, it supports the printing of Form form support
Support the printing of super long logs, and solve the problem of Logcat 4K character truncation support
Support to remove the vertical line border to display the log when formatting. Handy for copying network requests to tools like Postman support
Support log level support
Support displaying the current thread name support
Support to exclude log display of some interfaces support

  • Rendering diagram
    with a horizontal line on the left side of the log

No horizontal line on the left side of the log

logging-interceptor default implementation

  • custom weblog
//框架内部默认实现方法
object AndroidLoggingInterceptor {
    @JvmOverloads
    @JvmStatic
    fun build(isDebug:Boolean = true, hideVerticalLine:Boolean = false, requestTag:String = "Request", responseTag:String = "Response"): LoggingInterceptor {
        init()
        return if (hideVerticalLine) {
            LoggingInterceptor.Builder()
                    .loggable(isDebug) // TODO: 发布到生产环境需要改成false
                    .androidPlatform()
                    .request()
                    .requestTag(requestTag)
                    .response()
                    .responseTag(responseTag)
                    .hideVerticalLine()// 隐藏竖线边框
                    .build()
        } else {
            LoggingInterceptor.Builder()
                    .loggable(isDebug) // TODO: 发布到生产环境需要改成false
                    .androidPlatform()
                    .request()
                    .requestTag(requestTag)
                    .response()
                    .responseTag(responseTag)
//                    .hideVerticalLine()// 隐藏竖线边框
                    .build()
        }
    }
}
 //普通网络日志显示写法
        val httpLoggingInterceptor = HttpLoggingInterceptor { message ->
            Log.e(
                "网络日志", message
            )
        }
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY

        //框架内部封装日志显示写法 hideVerticalLine = true代表隐藏横线
        val loggingInterceptor = AndroidLoggingInterceptor.build(hideVerticalLine = true)
	//需要显示日志带横线
	val loggingInterceptor = AndroidLoggingInterceptor.build()

Network configuration related

  • Do you need to enable https ignore certificate mode
//双重校验锁式-单例 封装NetApiService 方便直接快速调用简单的接口
val apiService: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    //type 为false 表示不使用htpps忽略证书验证
    NetworkApi.INSTANCE.getApi(ApiService::class.java, BASE_URL, false)
}
  • Network interceptor related configuration introduction
/**
     * 实现重写父类的setHttpClientBuilder方法,
     * 在这里可以添加拦截器,可以对 OkHttpClient.Builder 做任意操作
     */
    override fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder {
        builder.apply {
            /** 设置缓存配置 缓存最大10M */
            cache(Cache(File(appContext.cacheDir, "cxk_cache"), 10 * 1024 * 1024))
            /** 添加Cookies自动持久化 */
            cookieJar(cookieJar)
            /** 演示添加缓存拦截器 可传入缓存天数,不传默认7天 */
            addInterceptor(CacheInterceptor())
            /** 演示添加公共heads 注意要设置在日志拦截器之前,不然Log中会不显示head信息 */
            addInterceptor(MyHeadInterceptor())
            /** 演示添加缓存拦截器 可传入缓存天数,不传默认7天 */
            addInterceptor(CacheInterceptor())
	    /** 演示token过期拦截器演示 */
            addInterceptor(TokenOutInterceptor())
            /** 演示日志拦截器 您也可以自定义网络日志 */
            addInterceptor(loggingInterceptor)
            /** 超时时间 连接、读、写 */
            connectTimeout(10, TimeUnit.SECONDS)
            readTimeout(5, TimeUnit.SECONDS)
            writeTimeout(5, TimeUnit.SECONDS)
        }
        return builder
    }
  • Network download module introduction
   //生成apk名字时间戳
            val apkName = "inspection" + System.currentTimeMillis() + ".apk"
            downLoad(
                "TAG",
                url,
                FileUtil.getInstance().pluginRootPath,
                apkName,
                true,
		true,  //是否开启忽略https   true-开启   默认不开启
                object : OnDownLoadListener {
                    override fun onDownLoadPrepare(key: String) {
                        Log.i("TAG", "准备下载")
                    }

                    override fun onDownLoadError(
                        key: String,
                        throwable: Throwable
                    ) {
                        Log.i("TAG", "下载失败")
                    }

                    override fun onDownLoadSuccess(
                        key: String,
                        path: String,
                        size: Long
                    ) {
                        Log.i("TAG", "下载成功"+apkName)
                    }

                    override fun onDownLoadPause(key: String) {
                        Log.i("TAG", "下载暂停")
                    }

                    override fun onUpdate(
                        key: String,
                        progress: Int,
                        read: Long,
                        count: Long,
                        done: Boolean
                    ) {
                        Log.i("TAG", "下载中")
                    }
                })
  • api interface definition
interface ApiService {

    /**
     * 首页文章列表
     */
    @GET("article/list/0/json")
    suspend fun getEntryAndExitData(): ApiResponse<Data>

}
  • Network return format
{
    "data": ...,
    "errorCode": 0,
    "errorMsg": ""
}

The sample format is  the data format returned by the Android Api. If the errorCode is equal to 0, the request is successful, otherwise the request fails. From the developer's point of view, we mainly want to get the unpacking data-data, and we don't want to judge errorCode==0 every time . Whether the request is successful or failed At this time, we can inherit BaseResponse in the server return data base class and implement related methods:

data class ApiResponse<T>(var errorCode: Int, var errorMsg: String, var data: T) : BaseResponse<T>() {
    // 这里是示例,wanandroid 网站返回的 错误码为 0 就代表请求成功,请你根据自己的业务需求来编写
    override fun isSucces() = errorCode == 0
    override fun getResponseCode() = errorCode
    override fun getResponseData() = data
    override fun getResponseMsg() = errorMsg
}

Introduction to the use of Google Jetpack framework

  • In your project, you need to  build.gradle add in the file
buildFeatures {
        viewBinding = true
        dataBinding = true
    }
  • Activity request to play Android api case
 class MainActivity : BaseActivity<MainViewModel, ActivityMainBinding>() {

    private val mArticleListAdapter: ArticleListAdapter by lazy { ArticleListAdapter(arrayListOf()) }

    override fun initView(savedInstanceState: Bundle?) {
        mViewModel.apiArticleListData()
        initRv()
    }

    private fun initRv() {
        mDatabind.rvArticleList.init(LinearLayoutManager(this), mArticleListAdapter, false)

        mViewModel.getArticleListData().observe(this) {
            mArticleListAdapter.submitList(it.datas)
            mArticleListAdapter.notifyDataSetChanged()
        }
    }
}
  • The simple use of ViewModel is introduced as follows
class MainViewModel : BaseViewModel() {

    private var articleListData: MutableLiveData<Data> = MutableLiveData()
    
    /**
     * 网络请求
     */
    fun apiArticleListData() {
        request({ apiService.getEntryAndExitData()},{
            articleListData.value=it
        },{
            //失败
        },true)
    }


    /**
     * 获取数据
     */
    fun getArticleListData(): MutableLiveData<Data> {
        return articleListData
    }
}

common problem

  • When gradle-7.0 or above, some devices glide can not load the picture solution
<application
        ........
        android:requestLegacyExternalStorage="true"
        ........
	>

github address

github address: GitHub - cl-6666/mvvm-framework: A set of rapid development libraries based on Google's latest AAC architecture and MVVM design pattern

Guess you like

Origin blog.csdn.net/a214024475/article/details/130625856