应用RxJava的 .doOnNext() 操作符,在每个 intent、每个 intent 的结果和之后渲染到 view 上的状态上添加日志,我们序列化 view 状态为json对象(我们稍后来讨论这个)。
我们可以看一下这些 logs:
看一下这些 log,我们不仅可以看应用崩溃前的最新状态,而且可以看到用户达到这个状态的整个过程。为了更好的可读性,我已经强调了状态过滤,并且用_[…]_替换掉“数据”(这些项将被显示到 recycler view 上)。 因此,用户开启这个 app -加载第一页的意图。然后加载指示条显示"loadFirstPage"。然后,真的数据就被加载进来了(data[…])。 接下来用户滑动列表项并且到达了 recyclerView 的底部,这将触发加载下一页的意图去加载更多数据(分页),这将造成状态转换成"loadingNextPage":对。一旦下一页被加载的数据(data[…])已经被更新并且"loadNextPage":错误已经被矫正。用户第二次做同样的事情。并且它开始采用下拉刷新意图并且状态,状态转变为“loadingPullRefresh”:true。突然 App 崩溃了(没有更多之后的 log 信息)。
因此如何利用这些信息帮助我们修复这个 bug?显然,我们知道那个意图用户触发了,因此我们可以人工去复现 bug。此外,我们可以将我们的 app 的状态快照成 json。我们可以简单的将最后一个状态反序列化 json,并且成为我们的初始状态去修复这个 Bug:
String json =" {“data”:[…],“loadingFirstPage”:false,“loadingNextPage”:false,“loadingPullToRefresh”:false} ";
HomeViewState stateBeforeCrash = gson.fromJson(json, HomeViewState.class);
HomePresenter homePresenter = new HomePresenter(stateBeforeCrash);
然后,我们打开调试工具,触发下拉刷新的意图(intent)。它将出现在如果用户已经向下滑第二次滑到第二页没有更多的数据存在,并且,我们的 app 没有正确的处理,因此下拉刷新造成了崩溃。
总结
制作 app 的状态"快照"让我们的开发工作更加轻松。不仅我们可以容易的复现崩溃场景,另外,我们可以序列化状态去写回归测试,不用额外消耗任意代码。记住这仅仅适用于如果 app 的状态遵循单项数据流(被业务逻辑驱动),不变性和纯函数的原则。Model-View-Intent 带领我们去正确的方向,因此我们构建“可快照”的 app 是非常好和十分有用,这就是这种架构的“副作用”。
“可快照的” app 有什么缺点?显然我们序列化 app 的状态(例如:使用 Gson)。这将添加额外的计算时间。在我的一般大小的 app 中,首次使用 Gson 序列化需要大约 30 毫秒。因为 Gson 需要使用反射来扫描类去决定需要序列化的字段。随后的状态序列化在 Nexus 4 中平均需要花费 6 毫秒。当序列化运行在 .doOnNext() 这是一般运行在其他线程,但是,我 app 的用户不得不等 6 毫秒比那些没有快照的 app。我的观点是等 6 毫秒用户是很难察觉到。无论如何,关于快照状态的一个讨论是当崩溃发生时,从用户的设备通过崩溃日志工具向服务器上传的数据量是十分巨大的。如果用户连接着 wifi 没什么大不了的,但可能对于在使用手机流量的用户确实是一个问题。最后但是也很重要的一点,你也许泄露了伴随着状态的敏感数据的崩溃日志。要么就不要在上传的崩溃报告中去序列化那些敏感的数据(因此报告可能不完整并且几乎没啥用),要么就将这敏感数据加密(这可能需要一些额外的CPU时间)。
总结一下:就我个人而言,在给我的 app 做快照处理时我发现了很多益处,然而,你也不得不做一些权衡.也许你可以在内部版本或者 beta 版本上启用快照功能,看看在你自己的 app 上工作得如何。
红利:时间旅行
在开发时,如果可以拥有时间旅行的选择项,岂不美哉。也许嵌入一个调试侧边栏像 Jake Wharton 的 u2020 dome app。
所有我们需要类似于调试侧边栏只需要两个按钮“前一个状态”和“后一个状态”因此我们可以一步一步地从一个状态及时的到前一个状态(或下一个状态)。例如:如果我们已经做了一个 HTTP 请求作为状态变化的一部分,可以确定的是,在往前回溯时,我们并不想再次进行真正的 http 请求,因为与此同时后端的数据也可能会发生变化。
时间旅行要求一些额外的层,像一个代理层在一个 app 的边界部分。因此我们可以“录制”和“回放”状态像 http 请求(同理 sqlite等等)。对这类事情十分的感兴趣?这就像我的朋友 Felipe 为OKHttp做类似的事情。可以随意联系他来得到他正在写的库的更多细节。
你是否正在找一个十分有用的安卓库,可以录制和回放 OkHttp 网络交互,比如说 Espresso 测试?
— Felipe Lima (@felipecsl) 28. Februar 2017
这篇博客是使用 MVI 开发响应式 APP 的一部分。 这里是内容表:
- Part 1: Model
- Part 2: View and Intent
- Part 3: State Reducer
- Part 4: Independent UI Components
- Part 5: Debugging with ease
- Part 6: Restoring State
- Part 7: Timing (SingleLiveEvent problem)
这是中文翻译: - 第一部分:Model
- 第二部分:View 和 Intent
- 第三部分:状态折叠器
- 第四部分:独立 UI 组件开发
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
设计模式学习笔记
设计模式系列学习视频
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中…(img-7r7VOjmg-1712679873144)]