项目github地址
项目简介
项目使用的是mvvm框架,使用了LifeCycle、ViewModel、LiveData,由于DataBind的复杂性,此项目并没有采用,使用了kotlin-android-extensions替代ViewBinding
关于项目组件化开发实现、各个模块功能在github项目中已有介绍,项目中封装了网络请求、图片请求、工具类、通用控件等,详细内容可阅读github项目中baselib和widgetlib
该文章简单介绍下框架的搭建以及一些个人认为比较好的亮点
为什么使用MVVM框架
mvc是老大哥了,解决了业务逻辑和数据操作的分离;mvp算是二哥了,基于老大哥的优点更上一层楼,将业务逻辑下放至P层,M层和V层不直接引用,P层做为业务逻辑处理层同时承担了承上启下的任务。说说mvvm小老弟吧,在使用mvp框架开发的时候很好的实现了业务数据视图的分层,但是为了这个优点我们需要写大量的契约类和接口
该项目是基于mvvm框架进行设计的,出了能减少创建契约类和接口外,mvvm通过观察者模式避免了业务层和视图层的双向引用,得益于LifeCycle相关功能mvvm框架使我们更加方便的对生命周期的管理,mvvm中的协程让我们进行异步操作更加方便和高效
关于Retrofit结合协程的使用
在ViewModel中自带了viewModelScope协程,在Activity或者Fragment销毁的时候该协程也会结束,使用Retrofit在viewModelScope协程的子线程中进行同步网络请求可以在协程关闭的时候网络请求也关闭,避免页面销毁了后网络请求回调造成的空指针情况,示例代码如下,具体参考项目中的封装
/**
* 发送请求
*
* @param scope 网络请求的协程
* @param listener 请求完成后的回调
* 请求返回的数据对应的类型,第一层必须继承 BaseResponse
*/
fun sendRequest(scope: CoroutineScope, call: Call, listener: RequestListener) {
if (!NetworkUtil.isNetworkAvailable(ContextUtil.getContext())) {
listener.requestError(
null, RequestErrorType.NO_INTERNET, "网络连接失败", CodeConstant.REQUEST_FAILD_CODE
)
return
}
scope.launch(Dispatchers.Main){
try {
val response = withContext(Dispatchers.IO){ call.execute()}
val code = response.code()
when {
code !=200 -> checkErrorCode(code, listener)
response.body() ==null -> listener.requestError(
null, RequestErrorType.COMMON_ERROR, "返回数据为空!", code
)
else -> sendRequestSuccess(response, listener)
}
}catch (e: Exception) {
listener.requestError(
null, RequestErrorType.COMMON_ERROR, "请求失败", CodeConstant.REQUEST_FAILD_CODE
)
}
}
}