android mvvm框架搭建_轻松搭建基于JetPack组件的MVVM框架
原文链接:轻松搭建基于JetPack组件的MVVM框架 - 掘金
Brick
github gitee
介绍
辅助android开发者搭建基于JetPack组件构建MVVM框架的注解处理框架。通过注解自动生成ViewModel的Factory类、lazy方法等;支持在项目的任意位置注入ROOM的dao层接口与Retrofit库中的api接口。
特点
android开发者
可以将brick
理解为一个轻量级的注入框架,使用非常简单,使用4-6个注解即可工作。brick
主要在编译期工作, 不会在App
运行时产生任何额外的性能消耗 ,并且只有1个注解库会打包到你的android
工程中,不用担心体积增大的问题。
适用范围
- 使用
androidx
而非support
库。 - 使用
JetPack
的ViewModel
组件。 - 使用
Retrofit
作为网络请求库。 - 使用
ROOM
数据库框架。(可选) - 服务端为多端口、多IP的项目。(可选)
引入
- 在你的android工程的根目录下的build.gradle文件中的适当的位置添加以下代码:
buildscript {...ext {brick_version = '0.2.0'}repositories {...maven { url 'https://jitpack.io' }}dependencies {classpath "com.gitee.numeron.brick:plugin:$brick_version"}
}allprojects {repositories {...maven { url 'https://jitpack.io' }}
}
复制代码
- 在你的android工程中要启用brick的android模块的build.gradle文件中的适当位置添加以下代码:
...
apply plugin: 'kotlin-kapt'
apply plugin: 'brick'
...
dependencies {...implementation "com.gitee.numeron.brick:annotation:$brick_version"kapt "com.gitee.numeron.brick:compiler:$brick_version"
}
复制代码
使用
一、 @Provide注解的使用方法:
- 在你编写好的ViewModel子类上添加@Provide注解
@Provide
class WxAuthorViewModel: ViewModel() {...
}
复制代码
- 有3种方式让brick注解处理器开始工作:
- 在Terminal终端上输入
gradlew :[ModuleName]:kaptDebugKotlin
运行脚本; - 在AndroidStudio右侧Gradle扩展栏中依次找到
[PrjectName] -> [ModuneName] -> Tasks -> other -> kaptDebugKotlin
并双击运行脚本; Ctrl + F9
编译整个项目。以上三种方式任选其一即可运行brick注解处理器。
- 脚本运行结束后,会生成两个包级方法:
lazyWxAuthorViewModel()
扩展方法,在Activity或Fragment中直接调用即可。get()
方法,在不方便使用lazy方法时,可使用此方法获取ViewModel的实例。注:lazyWxAuthorViewModel
方法就是对get()
方法的包装。
直接使用生成的方法,即可创建对应的ViewModel实例:
private val wxAuthorViewModel by lazyWxAuthorViewModel()
复制代码
或在onCreate()之后,通过get创建:
private lateinit var wxAuthorViewModel: WxAuthorViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)wxAuthorViewModel = get(this)
}
复制代码
二、 @Inject注解的使用方法
-2. (必需) 在获取Retrofit
实例的方法上添加@RetrofitInstance
,如:
@RetrofitInstance
val retrofit: Retrofit by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {Retrofit.Builder().client(okHttpClient).baseUrl(WANDROID_BASE_URL).addConverterFactory(MoshiConverterFactory.create()).build()
}val okHttpClient: OkHttpClient by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {val logInterceptor = HttpLoggingInterceptor()logInterceptor.level = HttpLoggingInterceptor.Level.BODYOkHttpClient.Builder().addInterceptor(logInterceptor).callTimeout(15, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).connectTimeout(15, TimeUnit.SECONDS).build()
}
复制代码
注:@RetrofitInstance
注解只能标记在public
修饰的val
属性上或方法上,val
属性上或方法可以在object 单例
或companion object
中,也可以是包级属性/方法。
-1. (可选) 在获取RoomDatabase
实例的属性或方法上标记@RoomInstance
,如:
@RoomInstance
val wandroidDatabase: WandroidDatabase by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {Room.databaseBuilder(CONTEXT, WandroidDatabase::class.java, "wandroid.db").build()
}
复制代码
注:@RoomInstance
注解只能标记在public
修饰的val
属性上或方法上,val
属性上或方法可以在object 单例
或companion object
中,也可以是包级属性/方法。
- 假设已有
Retrofit Api
接口和WxAuthorRepo
类
interface WxAuthorApi {@GET("wxarticle/chapters/json ")suspend fun getWxAuthorList(): List<WxAuthor>
}class WxAuthorRepo {...
}复制代码
- 在WxAuthorRepo中添加
lateinit var
修饰的WxAuthorApi
字段,并用@Inject
标记:
class WxAuthorRepo {@Injectlateinit var wxAuthorApi: WxAuthorApi}
复制代码
- 在ViewModel中创建
lateinit var
修饰的WxAuthorRepo
字段,并用@Inject
标记:
@Provide
class WxAuthorViewModel: ViewModel() {@Injectprivate lateinit var wxAuthorRepo: WxAuthorRepo
}
复制代码
标记后,继续编写业务代码即可,所有被@Inject
标记的字段,都会在编译期自动获取或创建实例,无需担心它们在何时被赋值。注:虽然是lateinit var
修饰的字段,但是不要尝试为它们赋值,这会导致致命的错误。注:@Inject
可以注入的类型只有Retrofit
的api
接口和ROOM
的dao
接口、以及有无参构造的类。
三、 多服务器或多端口的处理方法:
假设有另一个Retrofit api接口,它的访问地址或端口与baseUrl
中的不一样,此时,可以在Retrofit
的api
接口上添加@Port
和@Url
注解来设置它们的url或port。
@Port
的使用:
@Port(1080)
interface ArticleApi {@GET("wxarticle/list/{chapterId}/{page}/json")suspend fun getArticleList(@Path("chapterId") chapterId: Int, @Path("page") page: Int): Paged<Article>}
复制代码
添加此注解后,brick会在编译期根据@RetrofitInstance
注解标记的Retrofit
实例和@Port
的端口号,重新创建一个Retrofit
实例,并使用新的Retrofit
实例创建ArticleApi
的实例。
@Url
的使用:
@Url("http://www.wanandroid.com:1080/")
interface ArticleApi {@GET("wxarticle/list/{chapterId}/{page}/json")suspend fun getArticleList(@Path("chapterId") chapterId: Int, @Path("page") page: Int): Paged<Article>
}
复制代码
与@Port
的使用基本一致,实现的原理也是一样的。
附录1
生成的WxAuthorViewModels.kt
文件:
//kotlin 扩展方法,在Activity/Fragment中通过by调用
fun ViewModelStoreOwner.lazyWxAuthorViewModel(): Lazy<WxAuthorViewModel> =LazyWeChatAuthorViewModel(this)//包级方法,在Activity/Fragment的onCreate方法之后调用
fun get(owner: ViewModelStoreOwner): WxAuthorViewModel {val factory = WxAuthorViewModelFactory()return ViewModelProvider(owner, factory).get(WxAuthorViewModel::class.java)
}private class WxAuthorViewModelFactory : ViewModelProvider.Factory {@Suppress("UNCHECKED_CAST")override fun <VM : ViewModel> create(clazz: Class<VM>): VM = WxAuthorViewModel() as VM
}private class LazyWxAuthorViewModel(private val owner: ViewModelStoreOwner
) : Lazy<WxAuthorViewModel> {private var _value: WxAuthorViewModel? = nulloverride val value: WxAuthorViewModelget() {if(_value == null) {_value = get(owner)}return _value!!}override fun isInitialized(): Boolean = _value != null
}
复制代码
附录2
反编译后的WxAuthorViewModel.class
:
class WxAuthorViewModel extends ViewModel {private final WxAuthorRepo wxAuthorRepo = new WxAuthorRepo();}
复制代码
附录3
反编译后的WxAuthorRepo.class
:
class WxAuthorRepo {private final WxAuthorApi wxAuthorApi = RuntimeKt.getRetrofit().create(WxAuthorApi.class);public final WxAuthorApi getWxAuthorApi() {...return wxAuthorApi;}}
复制代码
附录4
WxAuthorApi
添加@Port
注解后的WxAuthorRepo.class
:
class WxAuthorRepo {private final WxAuthorApi wxAuthorApi = newRetrofit(RuntimeKt.getRetrofit(), 1080, null).create(WxAuthorApi.class);public final WxAuthorApi getWxAuthorApi() {...return wxAuthorApi;}private final Retrofit newRetrofit(Retrofit retrofit, int port, String url) {if (port > 0) {HttpUrl httpUrl = retrofit.baseUrl().newBuilder().port(port).build();return retrofit.newBuilder().baseUrl(httpUrl).build();} else if(url != null && url.length() != 0) {return retrofit.newBuilder().baseUrl(url).build();}return retrofit;}}
复制代码
总结
通过反编译class
后的代码以及整篇文章后可以得出一个大概的结论:brick
就是在java
编译成class
后,class
编译成dex
之前,对class
的字节码进行修改,给@Inject
标记的字段赋值,实现的注入框架。 目前对ViewModel
的注入还需要手动调用生成的方法来初始化,这在编译代码之前,AS上都会有红色的错误标记,接下来,让@Inject
支持ViewModel
的创建就是主要工作啦,等完成后,再发文章吧。## 写在最后
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料免费分享出来。
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。包含知识脉络 + 诸多细节,由于篇幅有限,下面只是以图片的形式给大家展示一部分。
【Android学习PDF+学习视频+面试文档+知识点笔记】
【Android高级架构视频学习资源】
Android部分精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
【Android进阶学习视频】、【全套Android面试秘籍】可以简信我【学习】查看免费领取方式!
android mvvm框架搭建_轻松搭建基于JetPack组件的MVVM框架相关推荐
- vsscode beego 没有提示_轻松搭建基于 Serverless 的 Go 应用(Gin、Beego 举例)
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计 ...
- thinkphp v5.0.24 密码爆破_轻松搭建基于 Serverless 的 ThinkPHP 应用
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计 ...
- java框架谁搭建_从零开始搭建一个开发框架(Java + Hibernate + Spring + Oracle)
框架使用的系统技术以及数据库如下: 技术:Java/Hibernate/Hibernate Annotation/Spring 数据库:Oracle 10g 整个框架的搭建步骤大致分为以下三步: 1. ...
- mysql双机热备 读写分离_轻松搭建MySQL主从复制、读写分离双机热备)
注意:如果此步骤始终为空设置(0.00秒),则表示先前的my.cnf配置不正确,请返回并重试检查配置步骤. (从)数据库中的配置 1.修改从属库的数据库配置文件 [root @ localhost]# ...
- e盘是否具有读写权限_轻松搭建MySQL主从复制、读写分离(双机热备)
主从复制: 当mysql数据库的数据量太大的时候,查询数据就很吃力了,无论怎么优化都会产生瓶颈,这时我们需要增加服务器设备来实现分布式数据库,实现多机热备份,要想实现多机的热备,首先要了解主从数据库服 ...
- mysql双机热备 读写分离_轻松搭建MySQL主从复制、读写分离(双机热备)
主从复制: 当mysql数据库的数据量太大的时候,查询数据就很吃力了,无论怎么优化都会产生瓶颈,这时我们需要增加服务器设备来实现分布式数据库,实现多机热备份,要想实现多机的热备,首先要了解主从数据库服 ...
- jenkins搭建_如何搭建移动端自动化测试平台?没错,就用Jenkins!
环境搭建 stf和Jenkins的安装过程这里不做说明,可以网上查找资料,这里只说一下注意的地方和需要的插件以及插件的配置. stf环境搭建 stf的环境搭建坑比较多,对node和npm的版本不对会出 ...
- 虚拟ip是什么意思_轻松了解基于Ip,Mac,组播的Valn是什么意思,通信基础第17篇...
通信知识第17篇:在上一篇中介绍了一文轻松了解Mac引入Valn,老化机制,转发流程通信基础概念16 本节内容主要深入理解valn相关概念,接下来的章节会对二层通信知识点进行系统讲解. VLAN相关基 ...
- centos java服务器搭建_从零开始搭建CentOS 7服务器配置JavaWeb环境
1.搭建FTP服务器 登录Linux,输入yum -y install vsftpd,安装vsftpd软件 显示如下,即代表安装完成 配置vsftpd 输入vi /etc/vsftpd/vsftpd. ...
最新文章
- VM 下装ubuntu系统
- 在人脸识别的时候,一定要穿上衣服啊!
- 洛谷P2158仪仗队(数学,观察找规律,欧拉函数)
- 安装python3.9
- 知乎: 如何评价阿里开源的企业级 Node.js 框架 egg? #18
- vnc报错 font catalog is not properly configured
- python调用activateMQ进行数据传输
- 转载:从地理学透视中国现代化
- 一周信创舆情观察(6.15~6.21)
- 视频教程-CCNA之TCP/IP协议栈精讲-思科认证
- 数据库系统工程师怎么备考?
- FFmpeg入门详解之74:FFmpeg转码器Java版之需求规格说明书
- C# 读取TXT文本文档 搜索指定字符串所在的行 保存到集合
- windows server 2008 R2 怎么集成USB3.0驱动
- 单片机 STM32 HAL IO扩展 PCA9555
- 故障--桥接网卡的坑
- mysql列插入数据
- 老夫金钟罩铁布衫纵横江湖数十年
- 直接分享5个T的网盘资源
- 学生计算机测评安排,计算机系学生综合素质测评办法(修改)