有用 AAC 的旁友吗,有个 LiveData 的问题想请教

2019-07-30 18:15:04 +08:00
 ukyoo
假设我当前使用 RxJava 的 Flowable 作为数据源, 我应当在 Repository 里就把 Flowable 转换成 LiveData 返回, 还是在 ViewModel 的 Flowable.subscribe( )里调用 LiveData#setValue()呢, 哪个更合适呢.
如果是 Repository 返回, 那 ViewModel 里的 val LiveData 又无法指向新的 LiveData 对象,如果用 Transformations.switchMap(sourceLiveData)处理又不是每次都能有输入参数来给你观察的,比如我点击 N 次.

如果是后者,感觉加工 LiveData 的过程又不应该交给 ViewModel 来处理.
5881 次点击
所在节点    Android
7 条回复
2bab
2019-08-02 09:12:31 +08:00
后者,因为:

1. LiveData 就是真实值的包装,长期可观察的对象,确实如你所言我觉得不可以也不应该不断指向新的对象;
2. LiveData 是和 Android Framework 本身有关联的(或者说和 LifeCycle Framework ),而 Repository 层面其实是更加底层、通用层面,可以不做关心,这也是你为什么用更重量级更通用的 Rx Framework 在这一层来处理逻辑和数据的原因吧,故放在 ViewModel 挺合理,楼主可以说一下为什么感觉不合理~
ukyoo
2019-08-02 09:42:25 +08:00
@2bab Hi, 这么做不是不可以.我是这么想的, 既然已经用了 Repository,在 ViewModel 只是应该调用 Repo 来直接获取加工好的数据, ViewModel 应该只负责向 View 层提供 LiveData.
参考官方的 arch_browse_sample 里, 成功失败的状态和数据都是在 Repo 里包装的,ViewModel 里直接通过 Repo 获取 LiveData. 但是官方的例子大量使用了 Transformations.flatMap(sourceLiveData), 在实际开发中不可能一直有 sourceLivedata 来观测, 比如我只是点击一下这时候是没有输入参数的,这时就不能借助 flatMap..所以我在 arch_sample 下提了个 issue:
https://github.com/googlesamples/android-architecture-components/issues/686

别的帖子里大佬的思路: 把 ViewModel 里 LiveData 的引用传递给 Repo
https://i.loli.net/2019/07/30/5d40467b25b8b95582.png
2bab
2019-08-02 10:34:34 +08:00
@ukyoo 我觉得你说的很具体了,那可以讨论一下几个具体的点:

1. ",在 ViewModel 只是应该调用 Repo 来直接获取加工好的数据":这点可以这样考虑,比如同样一个购物车信息的 Repo 可以被多个地方调用(甚至是同一个 Repo 的同一个 API ),但展示出来的方式可能略有不同,所以你可能会分别在 ViewModel 内做一些针对不同 UI 元素的数据后置处理(比如把给每个标题加上 1234 的顺序索引),我觉得 Repo 不需要承担 100% 的源数据处理工作,更多的是做好偏下层的通用性处理,ViewModel 可以有一点点真正对 "View" 的 "Model" 的处理;
2. "把 ViewModel 里 LiveData 的引用传递给 Repo":正如前面讨论的,LiveData 更多是要在 ViewModel 和 View 这边去发挥作用,而 Repo 本身是可以被更多地方使用,例如几个 Repo 之间可以互相调用,也即现在比较普遍的模块化框架下几个模块之间的功能互相 invoke,这种情况下我们并不需要 LiveData,而是使用如题所说的 Rx,如果要做这个方案,那么就得把大量的 Repo 里的 API 提供两套接口,一套没有 LiveData 一套有,不过也不能说不是一种解法吧。
ukyoo
2019-08-02 19:21:35 +08:00
@2bab 嗯哈怎么写都可以...只是想看看官方的最佳实践, "advanced" browseSample 还是不够
colaman
2019-08-08 10:22:46 +08:00
livedata 实际上更应该是对于结果 /状态的发射,而不是像我们以前的一个 rxjava 流一样做各种变换操作,官方有 livedata 和 Observable 的转换方法,但是实际上不适用于 RxJava,如果是用原本的 Retrofit+Rxjava 的 方式来写,确实更应该在数据变换完之后用 livedata 发射出去,只是这样看起来有点多余。如果用 kotlin 协程来写的话就显得比较简洁有效了
ukyoo
2019-08-08 11:24:25 +08:00
@colaman LiveDataReactiveStreams 没法处理 rxjava 的 onError, 这个不满足我现在的需求. 我没用过协程,请问协程怎么处理异常啊, 用 CoroutineExceptionHandler 吗?
colaman
2019-10-18 13:36:58 +08:00
@ukyoo 协程按照官方的处理是 try catch 这种最基础的写法,但是可以自己封装一下代码块或者 CoroutineExceptionHandler 都是可以的,看自己喜欢哪种思路。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/587604

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX