在Android上使用Firebase Cloud Messaging时,通常希望将传入的推送通知通知当前Activity
。推荐的一种方法是使用LocalBroadcastManager
将Intent
实现中的FirebaseMessagingService
发送到Activity
(StackOverflow example answer)。>
但是,从1.1.0-alpha01(2018-12-17)版本开始,LocalBroadcastManager
is deprecated:
LocalBroadcastManager是应用程序范围的事件总线,在您的应用程序中包含违反层的行为:任何组件都可以侦听其他任何事件。您可以将
LocalBroadcastManager
的用法替换为可观察模式的其他实现,具体取决于您的用例,这些选项可能是LiveData或响应流。
尽管此类很可能会保留更长的时间,但我还是想开始清理我们的应用程序,因此我想迁移到更好的东西,然后Google真正删除旧方法。
现在,这些本地广播在我们的应用程序中扮演两个主要角色:
Activity
都有一个广播接收器,该接收器侦听适当的消息并更新自己的视图数据。如我所见,这些用例在两个建议的替代方案上都有问题:
LiveData
最容易在Activity
中作为Fragment
或ViewModel
使用。但是,ViewModel
仅用于直接处理UI的那些类。从ViewModel
内部访问FirebaseMessagingService
的做法很丑陋,从架构的角度来看,这是一个非常糟糕的主意。另外,不同的活动和片段具有不同的ViewModel
对象,并且我不希望该服务需要全部访问它们。object
属性的Kotlin LiveData
(也称为Singleton),让FirebaseMessagingService
从传入消息中更新那些LiveData
对象,并让Activity
观察这些更改并将其复制到其自己的ViewModel
的{{1}}属性中。问题是双重的:首先,它要求我为每个数据段使用两个相同的LiveData
对象,一个在LiveData
中,一个在ViewModel
中。其次,它对处理“注销事件”没有帮助,因为object
是用来处理变化的数据,而不是监听事件流的。 (我也许可以使用此LiveData
Event Wrapper处理第二个问题,但是对于某些不适合这种方式的事情,这仍然感觉很糟糕。)我发现一个建议是将Kotlin Coroutines与LiveData
或Channel
s一起使用。它们可以与响应流非常相似地使用,但是(与RxJava不同)旨在与Kotlin一起使用,并受益于Kotlin对Java的改进。由于Google宣布他们将重点放在Kotlin而不是Java上,因此该选项特别具有吸引力。
虽然在我看来这是最好的选择,但我还没有从其他人那里获得任何反馈,有关该反馈是否有效以及这种实现是否有副作用和/或陷阱。我发现的唯一一件事是Flow
存储库中的open issue,有关需要提供这样一个应用程序示例的需求。尽管我很乐意提供这样的示例,但我认为我对它的了解还不够,无法创建一个很好的示例,并且我不希望我的生产应用成为豚鼠。我也不知道在这种情况下将显式的协程与kotlinx.coroutines
一起使用还是将Channel
与suspend
一起使用是否更好(或更合适)。
总结:
Flow
和Service
之间通信的好方法?Activity
或Channel
是哪种更适合使用Kotlin类型?答案 0 :(得分:2)
协程对于将数据从一个软件组件传递到另一软件组件并没有真正帮助。它们使用看起来好像是同步的语法来帮助处理异步工作的多个单元。那是协程的底线。它们类似于JavaScript中的async / await语法。虽然您可能使用协程从异步源访问数据,但它并没有给您任何原始手段将数据代理到其他组件上。
LiveData可能可以很好地满足您的需求。不要将ViewModel与LiveData混淆-它们可以解决不同的问题。尽管您正确地认为ViewModel仅应由处理UI的代码访问,但该准则不会扩展到LiveData。公开一个反映FirebaseMessagingService中当前数据的LiveData,这是合理的,以后再由ViewModel拾取,转换并传递给视图。此LiveData可以是单例,也可以通过您选择的任何依赖项注入基础结构来获取。
请记住,LiveData实际上仅应用于管理状态更改。这不是您的应用程序可以收听的数据“流”。您需要确保您的基础架构是基于状态的,以使其正常运行。 FCM本身不是基于状态的,但是如果您希望您的视图响应来自FCM的消息,则需要在每条消息之间保留足够的上下文,以确保您的UI对新消息(或完全没有消息)做出一致的响应。