前言

在前一篇中,介绍了 KtArmor—MVVM 简单的使用方法,但是这往往不是全部。

在持续迭代、维护下,发现功能越写越多,也相应复杂起来。

所以后续,我尽可能编写详细 说明文档,并且在源码编写 注释

废话不多说,进入正文。

ViewModel

回到上文所说的 Login 示例,我们在 LoginViewModel,通过quickLaunch DSL 方式,发起网络请求。如下代码所示:

class LoginViewModel : BaseViewModel<LoginRepository>() {val loginData = MutableLiveData<LoginRsp>()fun login(account: String, password: String) {...省略其他代码// DSL 方式发起 网络请求quickLaunch<LoginRsp> {onStart { showLoading() }request { repository.login(account, password) }onSuccess { loginData.value = it }}}
}

quickLaunch 方法,需传入范型( 返回值类型),即调用 repository.login(account, password) 返回值类型, 且必须实现 KResponse 接口,如下代码所示:

@POST(API.LOGIN)
suspend fun login(@Query("username") username: String,@Query("password") password: String): BaseResponse<LoginRsp>

KResponse

由于 quickLaunch DSL 方式默认实现了 Success,Failure 逻辑处理,并且进行相应回调。所以 Retrofit 的 api service 返回的 BaseResponse,必须实现 KResponse 接口

KResponse 实现如下:

data class BaseResponse<T>(var data: T?,var errorCode: Int = -1,var errorMsg: String = "") : KResponse<T> {override fun isSuccess(): Boolean = errorCode == 0override fun getKData(): T? = dataoverride fun getKMessage(): String? = errorMsg
}

以上是参考代码,根据后台接口返回的类型,新建一个 基类 Response(BaseResponse),实现 KResponse 接口,并且实现对应的方法

  • isSuccess(必须)
  • getKData(必须)
  • getKMessage(必须)
  • executeRsp
  • execute

其中 executeRsp,execute 默认实现了 默认的处理逻辑,如下所示

/***  全局默认实现, 可根据自身业务 重写execute方法*  @param error            若有错误的回调, 默认getKMessage(), 否则返回 Setting.MESSAGE_EMPTY*  @param successResponse  成功的回调, 默认是返回 KResponse<T>*/
fun executeRsp(successResponse: ((KResponse<T>) -> Unit)?, error: ((String) -> Unit)? = null) {if (this.isSuccess()) {successResponse?.invoke(this)return}(this.getKMessage() ?: Setting.MESSAGE_EMPTY).let { error?.invoke(it) ?: Toasts.show(it) }
}/***  全局默认实现, 可根据自身业务 重写execute方法*  @param success          成功的回调, 默认是返回 getKData()*  @param error            若有错误的回调, 默认getKMessage(), 否则返回 Setting.MESSAGE_EMPTY*/
fun execute(success: ((T?) -> Unit)?, error: ((String) -> Unit)? = null) {if (this.isSuccess()) {success?.invoke(this.getKData())return}(this.getKMessage() ?: Setting.MESSAGE_EMPTY).let { error?.invoke(it) ?: Toasts.show(it)}
}

以 execute 为例,默认是 根据 isSuccess 判断是否成功,并且 回调到 quickLaunch 方法的 onSuccess、onFailure 方法。开发者可以根据自身需求,对 execute/executeRsp 方法重写

你以为这样就完事了吗?

扩展

一般情况下,我们获取了 repository 返回的数据,在 onSuccess 方法处理自己的业务逻辑。

然后 遇到异常,会进行如下操作:

  • toast 显示 message
  • print log。
  • hideLoading

如下代码所示:

 quickLaunch<LoginRsp> {request { repository.login(account, password) }onSuccess { loginSuccessData.value = it }onFailure { loginFailData.value = it }onException { loginExceptionLiveData = it }
}

由于 Activity 是通过观察 ViewModel 中 liveData 数据变化,进而做 请求成功,请求失败 等逻辑处理。

所以首先想到是 新增 三个 LiveData,来通知 Activity,但是每次请求,都需要如此操作,这时候需要封装一下了。

方案

KtArmor-MVVM, 尝试引入一个 复合 LiveData—— CommonLiveData,解决上面问题,
所谓 复合,本质就是 CommonLiveData,里面包含 两个LiveData,如下代码所示:

class CommonLiveData<T> : MutableLiveData<T>() {val errorLiveData = MutableLiveData<String>()... 省略其他
}

ViewModel

在ViewModel 中 使用方式如下

val loginData = CommonLiveData<LoginRsp>()// 看这里 ^^^^quickLaunch<LoginRsp> {request { repository.login(account, password) }onSuccess { loginData.value = it }onFailure { loginData.failureMessage = it }onException { loginData.exception = it }
}/*** 等同上面 quickLaunch*/
superLaunch(loginData) {request { repository.login(account, password) }
}

在原有基础上,MutableLiveData,切换成 CommonLiveData

并且新增一个 superLaunch DSL 方法,简化了 quickLaunch DSL 方法 的赋值操作

当然 你也可以根据自身业务,重写 onSuccess, onFailure, onException 等方法。

然后我们再来看看 Activity,代码上,就更加方便简单明了。

Activity

class LoginActivity : AppCompatActivity(), IMvmActivity {...省略其他代码override fun dataObserver() {// 正常 MutableLiveData 监听viewModel.loginData.observe(this, Observer {toast("登录成功")})// CommonLiveData 监听quickObserve(loginViewModel.loginData) {onSuccess {toast("登录成功")}onFailure { message ->toast(message)}onException { throwable ->toast(R.string.unkown_error)logd(msg)}}/*** CommonLiveData 监听, 等同上面, 只监听 Success 情况* onSuccess:  自定义实现* onFailure:  默认 toast message (viewModel 传递过来的 message)* onException: 默认 toast "未知异常"(固定), 打印 log*/quickObserveSuccess(loginViewModel.loginData) {toast("登录成功")}}
}

还是以 Login 示例,我们在 LoginActivity 中,需要 observe, LoginViewModel 中的 loginData,来获取 请求成功后的数据。

若是 使用了 CommonLiveData,则我们只需调用 quickObservequickObserveSuccess,即可监听到 ViewModel 传递过来的数据,进行相应的处理。

具体方法说明,都在上面代码注释所示。

自定义

看到这里,可能有小伙伴会说了,你的默认实现,不符合我的业务,不喜欢,想要修改,怎么办。

没问题!

KtArmor-MVVM 提供对应接口,给开发者进行自定义扩展

Activity

class MyActivityActuator : IActivityActuator {override fun <R> success(mvmView: IMvmView, data: R?) {}override fun failure(mvmView: IMvmView, message: String?) {}override fun exception(mvmView: IMvmView, throwable: Throwable?) {}}

新建 MyActivityActuator, 并且实现 IActivityActuator 接口,自定义 quickObserve 默认处理逻辑。

ViewModel ,也是同理。实现 ILiveDataActuator 接口,自定义 superLaunch 默认处理逻辑

ViewModel

class MyLiveDataActuator : ILiveDataActuator() {override fun <R> success(liveData: CommonLiveData<R>, data: R?) {}override fun <R> failure(liveData: CommonLiveData<R>, message: String?) {}override fun <R> exception(liveData: CommonLiveData<R>, throwable: Throwable?) {}
}

最后别忘了,需要 配置到 KtArmor 中,这样才会生效!

class BaseApplication : Application() {override fun onCreate() {super.onCreate()// KtArmor 相关配置with(KtArmor){configActivityActuator(MyActivityActuator())configLiveDataActuator(MyLiveDataActuator())}}
}

小结

代码整体实现上,相对简单,遵循开源框架的 三部曲,使得框架 可全局配置,可局部配置。

后续想到更好的方案,在进行优化,

不知你们意向如何? 期待小伙伴们更好方案 : )

最后

KtArmor-MVVM 框架是一款小而美的框架,也是我个人经验的积累, 总结,希望大家喜欢。

如果你有更好的建议欢迎 pr,issues 一起交流学习。

如有不妥, 望各位大佬指出。

KtArmor-MVVM 源码传送门

相关文章

MVVM

  • Kotlin的圣光机甲——KtArmor-MVVM(一)

MVP

  • Kotlin的魔能机甲——KtArmor(一)

  • Kotlin的魔能机甲——KtArmor插件篇(二)

  • Kotlin的魔能机甲——KtArmor(三)

  • Kotlin的魔能机甲——KtArmor网络调用封装(四)

下次再见

Kotlin的圣光机甲——KtArmor通用流程篇 (二)相关推荐

  1. Android构建流程——篇二

    文章目录 预操作 任务列表 如何查看一个task类 Task1: checkDebugClasspath 1. input/output 2. 如何找到任务实现类 3. 核心类(AppClasspat ...

  2. flowable笔记 - 简单的通用流程

    简介 通用流程可以用于一些基本的申请,例如请假.加班. 大致过程是: 1. 创建申请 2. 分配给审批人(需要审批人列表,当前审批人) -> 有下一个审批人 -> 3 -> 无 -& ...

  3. 程序员述职报告范文_物流人员述职报告范文(通用5篇)

    物流人员述职报告范文(通用5篇) 时间是看不见也摸不到的,就在你不注意的时候,它已经悄悄的和你擦肩而过,回顾过去的工作,倍感充实,收获良多,需要认真地为此写一份述职报告.你还在为写述职报告而苦恼吗?以 ...

  4. Liferay7 BPM门户开发之10: 通用流程实现从Servlet到Portlet(Part1)

    开发目的: 实现通用流程自动化处理(即实现不需要hardcode代码的bpm统一处理后台,仅需要写少量前端html form代码和拖拽设计BPM定义) 既可独立运行或可依托于Liferay或依托其它门 ...

  5. 计算机教师帮扶记录,教师结对帮扶工作总结范文(通用6篇)

    教师结对帮扶工作总结范文(通用6篇) 不经意间,一段时间的工作已经结束了,回顾这段时间,我们的工作能力.经验都有所成长,不妨坐下来好好写写工作总结吧!那么你有了解过工作总结吗?下面是小编收集整理的教师 ...

  6. 小学数学与计算机整合课优质教案,小学数学优质课教案《长方形的面积》(通用5篇)...

    小学数学优质课教案<长方形的面积>(通用5篇) 作为一名无私奉献的老师,编写教案是必不可少的,教案是教学活动的依据,有着重要的地位.怎样写教案才更能起到其作用呢?以下是小编为大家收集的小学 ...

  7. 小学计算机国培研修总结,小学数学教师国培研修总结(通用5篇)

    小学数学教师国培研修总结(通用5篇) 总结在一个时期.一个年度.一个阶段对学习和工作生活等情况加以回顾和分析的一种书面材料,它能使我们及时找出错误并改正,让我们好好写一份总结吧.总结怎么写才是正确的呢 ...

  8. Kotlin从小白到大牛第1篇 【Kotlin】基础视频课程-关东升-专题视频课程

    Kotlin从小白到大牛第1篇 [Kotlin]基础视频课程-7239人已学习 课程介绍         本视频是智捷课堂推出的一套"Kotlin语言学习立体教程"的视频第一部分, ...

  9. 【MOT】多目标跟踪通用流程方法总结

    从整体框架分类: TBD(Tracking-by-Detecton),或者DBT(Detection-based-Tracking),具体来说首先使用物体检测器检测目标,然后,利用运动.位置.外观线索 ...

最新文章

  1. java程序员可以只用windos吗_程序员要写多少代码 才能开发一个window操作系统
  2. ASP.NET 快乐建站系列–2. Rad Controls 简介
  3. [裴礼文数学分析中的典型问题与方法习题参考解答]4.3.23
  4. java模型给泛型_java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
  5. php spl_autoload_register() 函数
  6. a20添加usb2net的驱动方法
  7. python四分位数_分位函数(四分位数)概念与pandas中的quantile函数
  8. 有20万3年不用,怎样理财呢?
  9. Android大学课件SQLite3 数据库操作
  10. PAT1137 Final Grading
  11. DBCC--SHOWCONTIG
  12. 四、对象创建和垃圾回收流程
  13. 手把手教你二维数组打印
  14. 基于GD32F10x手动编程实现简易freertos实时操作系统
  15. oracle创建一个永久性表空间,Oracle表空间简单管理永久表空间
  16. spark统计pv和uv值
  17. 计算机图形学(第四版)-第一个画线例子- 读书笔记P30
  18. AV1比HEVC/H.265简单对比
  19. c++画直线、矩形、圆、椭圆
  20. 100万并发连接服务器

热门文章

  1. 数据库系统概论第三章学习通作业(建表、查询、修改、删除、视图)
  2. snprintf 与 vsnprintf
  3. 爱奇艺等43款APP被“通报”,个人信息保护法将提供“新护法”
  4. 通讯软件化及业务流程集成
  5. IOS 使用CoreLocation实现定位(Swift版)
  6. Git: remote: aborting due to possible repository corruption on the remote side. 的解决办法
  7. Web前端开发技术第二版课后上机题(第四章)
  8. c语言 map 构造函数,map函数,map函数的作用
  9. xtrabackup throttle参数及相关问题分析
  10. 2023年网络文化经营许可证(文网文)办理流程