懒人必备Jetpack MVVM框架

news2024/11/24 17:42:13

目录

效果图

项目依赖

使用介绍

项目使用的三方库及其简单示例和资料

网络请求相关使用介绍

谷歌Jetpack框架使用介绍

常见问题

github地址


Android Jetpack MVVM框架开发,基于AndroidX开发,傻瓜式使用,适用于所有项目

谷歌 Android 团队 Jetpack 视图模型: 

效果图

项目依赖

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

Step 2. Add the dependency

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

使用介绍

项目使用的三方库及其简单示例和资料

  • Kotlin
  • Lifecycle
  • ViewModel
  • LiveData
  • ViewBinding
  • OkHttp:网络请求
  • PersistentCookieJar:持久CookieJar实现
  • logging-interceptor:网络日志
  • Retrofit:网络请求

网络请求相关使用介绍

网络日志使用介绍


api功能支持列表是否支持
支持http request、response的数据格式化的输出支持
当请求为Post时,支持Form表单的打印支持
支持超长日志的打印,解决了 Logcat 4K 字符截断的问题支持
支持格式化时去掉竖线边框显示日志。方便将网络请求复制到Postman之类的工具支持
支持日志级别支持
支持显示当前的线程名称支持
支持排除一些接口的日志显示支持

  • 效果图
    日志左边带横线

日志左边不带横线

logging-interceptor默认实现

  • 自定义网络日志
//框架内部默认实现方法
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()

网络配置相关

  • 是否需要打开https忽略证书模式
//双重校验锁式-单例 封装NetApiService 方便直接快速调用简单的接口
val apiService: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    //type 为false 表示不使用htpps忽略证书验证
    NetworkApi.INSTANCE.getApi(ApiService::class.java, BASE_URL, false)
}
  • 网络拦截器相关配置介绍
/**
     * 实现重写父类的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
    }
  • 网络下载模块介绍
   //生成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 ApiService {

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

}
  • 网络返回格式
{
    "data": ...,
    "errorCode": 0,
    "errorMsg": ""
}

该示例格式是 玩Android Api返回的数据格式,如果errorCode等于0 请求成功,否则请求失败 作为开发者的角度来说,我们主要是想得到脱壳数据-data,且不想每次都判断errorCode==0请求是否成功或失败 这时我们可以在服务器返回数据基类中继承BaseResponse,实现相关方法:

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
}

谷歌Jetpack框架使用介绍

  • 在你的项目,需要在 build.gradle 文件中加入
buildFeatures {
        viewBinding = true
        dataBinding = true
    }
  • Activity请求玩安卓api案例
 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()
        }
    }
}
  • ViewModel简单使用介绍如下
class MainViewModel : BaseViewModel() {

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


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

常见问题

  • 当gradle-7.0以上,部分设备glide加载不出图片解决方法
<application
        ........
        android:requestLegacyExternalStorage="true"
        ........
	>

github地址

github地址:GitHub - cl-6666/mvvm-framework: 基于谷歌最新AAC架构,MVVM设计模式的一套快速开发库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mathtype7中文版下载安装后如何关联word

随着网络时代的发展&#xff0c;许多数据都需要上传网络。无论是否是数学专业的师生&#xff0c;在平时的学习中常需要输入数学公式。可数学公式中文字部分少&#xff0c;公式中常包含许多特殊符号&#xff0c;虽然通过输入法可以输入某些特殊公式符号&#xff0c;但不完美&…

springboot项目外卖管理 day02-新增员工以及员工信息编辑

文章目录 一、新增员工1.1、需求分析1.2、数据模型1.3、代码开发 二、员工信息分页查询2.1、需求分析 2.2、代码开发2.3、分页插件2.4、员工信息分页查询 三、启用/禁用员工账号3.1、需求分析3.2、代码开发3.3、根据id修改员工信息3.4、代码修复 4、编辑员工信息4.1、功能需求4…

企业级信息系统开发讲课笔记4.6 Spring Boot整合MyBatis

文章目录 零、学习目标一、Spring Boot数据访问概述二、Spring Boot 整合MyBatis&#xff08;一&#xff09;基础环境搭建1、数据准备&#xff08;1&#xff09;创建博客数据库&#xff08;2&#xff09;创建文章表&#xff08;3&#xff09;文章表插入记录&#xff08;4&#…

protobuf 的安装

protobuf 的安装 安装步骤最后的解决办法git clone遇到的问题解决办法: 后续遇到的问题1.果然还是报错了: 2023-06-05更新Abseil的安装2023-06-06更新代码 安装步骤 这个博主的操作对我有效,这个写的好 apt-get install autoconf automake libtool curl make g unzip(成功) g…

【AUTOSAR】Bootloader说明(二)---- 初始化流程及配置

按照DSP复位后的执行情况&#xff0c;Boot-loader分为以下几部分&#xff1a; DSP启动及系统初始化RAM自检应用程序有效性检查UDS命令处理FALSH操作 DSP启动及系统初始化 选择从FLASH启动 DSP的启动模式配置为从FLASH启动【参考】&#xff0c;硬件引脚配置如下&#xff1a; 引…

Vue.js 中的 Nuxt.js 是什么?如何使用 Nuxt.js?

Vue.js 中的 Nuxt.js 是什么&#xff1f;如何使用 Nuxt.js&#xff1f; Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架&#xff0c;它提供了一种简单的方式来创建基于 Vue.js 的应用程序。Nuxt.js 提供了许多有用的功能&#xff0c;如自动路由、代码分割、服务端渲染等&…

你了解 .gitkeep文件吗?

目录 简介 作用 例程 简介 本文主要介绍在git中, .gitkeep的作用。 作用 git无法追踪一个空的文件夹&#xff0c;当用户需要追踪(track)一个空的文件夹的时候&#xff0c;按照惯例&#xff0c;大家会把一个称为.gitkeep的文件放在这些文件夹里。 例程 就个人而言&#…

VST的天花板?苹果Vision Pro解析

看了那么多预测、分析之后&#xff0c;苹果MR头显&#xff08;Apple Vision Pro&#xff09;真正的来了。 十多年前&#xff0c;Oculus Rift DK1开启了近代新一轮VR热潮。十年之后&#xff0c;发展未及预期&#xff0c;VR仍未走向大众。如今整个AR/VR行业都在期待&#xff0c;…

一文带你了解11个Linux最常用命令

文章目录 1. 前言2. 文件与目录的查看:ls3. 显示当前路径:pwd4. 创建目录:mkdir5. 切换目录:cd6. 创建文件:touch7. 查看指定文件:cat8. 向终端输出:echo9. 树形结构显示目录: tree10. 删除文件或目录: rm11.复制文件或目录: cp12.文本编辑器: vim13. 总结 1. 前言 Linux的命令…

强大交互功能,真实产品体验一步到位!

动态交互效果是原型项目的灵魂&#xff0c;也是原型与设计产出物的关键区别。一个好的交互设置不仅能准确地传达静态界面难以表达的逻辑、流程和细节体验&#xff0c;还能呈现出丰富精彩的视觉效果&#xff0c;提高项目的质量。对于产品经理来说&#xff0c;学会交互设计是必不…

教你一招,能解决90%的机房问题

近年来&#xff0c;随着科技的发展&#xff0c;蓄电池的使用十分普遍&#xff0c;而蓄电池的广泛应用&#xff0c;也出现了一系列的问题&#xff0c;如不及时处理&#xff0c;可能给系统造成更严重的损失。 为什么需要电池监控&#xff1f; 01.人工值班巡检已经不能满足机房电…

人工智能(pytorch)搭建模型8-利用pytorch搭建一个BiLSTM+CRF模型,实现简单的命名实体识别

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型8-利用pytorch搭建一个BiLSTMCRF模型&#xff0c;实现简单的命名实体识别&#xff0c;BiLSTMCRF 模型是一种常用的序列标注算法&#xff0c;可用于词性标注、分词、命名实体识别等任务。本…

chatgpt赋能python:Python如何到下一行

Python如何到下一行 Python是一种高级编程语言&#xff0c;因其简单易学、可读性高、广泛的应用领域与强大的工具库而迅速成为了广泛使用的语言之一。在Python编程中&#xff0c;换行操作是经常使用的操作。本文将介绍Python中的换行操作以及如何在代码中使用它。 换行符 换…

百度APP iOS端包体积50M优化实践(三) 资源优化

01 前言 百度APP iOS端包体积优化系列文章的前两篇重点介绍了包体积优化整体方案、各项优化收益和图片优化方案&#xff0c;图片优化是从无用图片、Asset Catalog和HEIC格式三个角度做深度优化。本文重点介绍资源优化&#xff0c;在百度APP实践中&#xff0c;资源优化包括大资…

存储过程和函数的区别

目录 零、基本格式 一、返回值 二、参数传递 1、存储过程 2、函数 三、执行方式 四、事务处理 1、存储过程 2、函数 五、数据库兼容性 课上老师提出的讨论题&#xff1a;存储过程和函数的区别&#xff1f; 有同学回复&#xff1a;在数据库后端编程中&#xff0c;存储…

Python数据攻略-Pandas的数据创建与基础特性

大家好&#xff0c;我是Mr数据杨&#xff01;今天将进入Python的Pandas数据世界&#xff0c;就像三国演义中的英雄们&#xff0c;用聪明才智塑造自己的命运。 记得三国中&#xff0c;周瑜曾利用兵法巧妙策划火烧赤壁&#xff0c;击败曹军。这就像创建一个Pandas DataFrame&…

布局量子计算工业应用!D-Wave正在“偷偷”干大事

​ &#xff08;图片来源&#xff1a;网络&#xff09; D-Wave 致力于让用户从量子计算中即时受益&#xff0c;而不必等到长远的未来。几十年来&#xff0c;这家加拿大公司一直努力将设备商业化&#xff0c;多家企业客户都在使用其量子计算来优化业务运营。例如&#xff0c;Pay…

Spark RDD容错机制

文章目录 一、RDD容错机制&#xff08;一&#xff09;血统方式&#xff08;二&#xff09;设置检查点方式 二、RDD检查点&#xff08;一&#xff09;RDD检查点机制&#xff08;二&#xff09;与RDD持久化的区别&#xff08;三&#xff09;RDD检查点案例演示 三、共享变量&#…

mysql数据库出现Too many connections以及磁盘满了的查看方式

Too many connections问题 这问题是数据库连接数太多了导致的&#xff0c; 两个排查方向 1、当用户数量大的时候 先查看最大连接数show variables like ‘%max_connections%’; 这里的最大连接数就是2000&#xff0c;够用了&#xff0c;一般500-1000就够了&#xff0c;内存多…

【干货分享】3D模型可视化、格式转换引擎和Parasolid如何集成?

​今天分享一个示例项目&#xff0c;该示例项目使用HOOPS链轮将HOOPS Exchange和Siemens Parasolid实施到HOOPS Visualize中。 HOOPS中文网http://techsoft3d.evget.com/↓ 点击下方视频查看详情 ↓ HOOPS Visualize - Exchange和Parasolid集成视频 正如您在上面的视频中看到…