我一直在苦苦思考,在新的Android推荐架构中,Android服务应该放在哪里。我想出了许多可能的解决方案,但我无法决定哪一个是最好的方法。
我做了很多研究,但我找不到任何有用的指南或教程。关于在我的应用架构中放置服务的唯一提示是这个,来自@JoseAlcerreca Media的帖子
理想情况下,ViewModels不应该了解Android。这提高了可测试性、泄漏安全性和模块化。一般的经验法则是确保没有android。*在ViewModels中导入(android.arch.*等例外)。这同样适用于演讲者。
因此,我应该将我的Android服务放在架构组件层次结构的顶部,与我的活动和片段处于同一级别。这是因为Android服务是Android框架的一部分,所以ViewModels不应该知道它们。
现在,我将简要解释我的场景,但只是为了使全景更清晰,而不是因为我想要这个特定场景的答案。
以下是我能想到的三种不同的体系结构:
AndroidService中的LiveData
更新:这是我当时个人采用的方法,因为它工作得很好,让我可以相对较快地完成。然而,我建议遵循Jeel Vankhede的更新答案,这似乎是一个更“惯用”的实现。
我很确定我应该把它们放在架构的顶部,把它们当作一个活动/片段来对待,因为BoundServices是Android框架的一部分,它们由Android操作系统管理,并与其他活动和片段绑定。在这种情况下,我不知道与LiveData、ViewModels和活动/片段交互的最佳方式是什么。
有些人可能认为它们应该被视为一个数据源(因为在我的例子中,它是使用蓝牙从秤上获取数据),但我认为这不是一个好主意,因为我在上一段中已经说过,特别是因为它在这里说:
避免将应用程序的入口点(如活动、服务和广播接收器)指定为数据源。相反,它们应该只与其他组件协调,以检索与该入口点相关的数据子集。每个应用程序组件的寿命都很短,这取决于用户与设备的交互以及系统当前的整体运行状况。
所以,最后,我的问题是:
我们应该把Android(绑定)服务放在哪里,它们与其他架构组件有什么关系?这些替代方案中有哪一个是好方法吗?
如果我们绑定/解除绑定到/从服务的活动或多个活动像往常一样在onstart/onStation,然后我们有单例实例,持有蓝牙相关管理器(我使用北欧lib为ble管理器)。这个实例在服务中,这样我们就可以断开连接,例如当服务被破坏时,因为用户界面与它解除了绑定,当服务被创建时,我们可以重新连接到ble。我们还将ble管理器单例注入到视图模型中,通过livedata或rx或ble管理器提供的类似的反应性数据,例如连接状态,使交互和数据监听变得更加容易。通过这种方式,我们可以从视图模型与ble、订阅特性等进行交互,服务提供了可以在多个活动中生存的范围,并且基本上知道何时连接或断开连接。我已经在我的应用程序中尝试过这种方法,到目前为止它还可以。
示例项目https://github.com/uberchilly/BoundServiceMVVM
在仍然能够使用Android服务的情况下,避免直接接触该服务的一种方法是通过接口对象。这是首字母缩略词SOLID中接口隔离“I”的一部分。下面是一个小例子:
public interface MyFriendlyInterface {
public boolean cleanMethodToAchieveBusinessFunctionality();
public boolean anotherCleanMethod();
}
public class MyInterfaceObject implements MyFriendlyInterface {
public boolean cleanMethodToAchieveBusinessFunctionality() {
BluetoothObject obj = android.Bluetooth.nastySubroutine();
android.Bluetooth.nastySubroutineTwo(obj);
}
public boolean anotherCleanMethod() {
android.Bluetooth.anotherMethodYourPresentersAndViewModelsShouldntSee();
}
}
public class MyViewModel {
private MyFriendlyInterface _myInterfaceObject;
public MyViewModel() {
_myInterfaceObject = new MyInterfaceObject();
_myInterfaceObject.cleanMethodToAchieveBusinessFunctionality();
}
}
鉴于上述范例,您可以自由地将服务放在包含POJO代码的包之外的包中。没有“正确”的位置来放置您的服务——但放置它们的位置肯定是错误的(例如,POJO代码所在的位置)。
在得到@Ibrahim Disouki(谢谢)的建议后,我深入挖掘,发现了一些有趣的东西!以下是背景。
O. P.寻求解决方案“考虑Android架构组件,Android框架的服务组件在哪里”。所以,这里是开箱即用的(SDK)解决方案。
它与活动/片段
处于同一水平。怎样如果你要扩展服务类,那么就开始扩展LifecycleService。这背后的原因很简单,以前我们必须依靠活动/片段生命周期来接收更新/对服务执行一些上下文操作。但现在情况并非如此。
现在,它有自己的生命周期注册表/维护者,称为ServiceLiefycleDispatcher,它负责服务的生命周期,这也使它成为生命周期所有者。
它留给我们的条件是,从现在开始,你可以有一个ViewModel
到LifececleService
为自己做操作
在O.P.的上下文中,LifecycleService现在可以维护它的ViewModel
来执行与存储库层相关的业务逻辑,之后在另一个生命周期感知组件上,如Activity/Fragment,也可以使用/重用相同的ViewModel
,对其进行特定操作。
请注意,通过这样做,您将处于两个不同的生命周期所有者
的状态(活动
(我建议不要通读)
在我看来,服务应该和活动/片段处于同一级别,因为它是框架组件
所以,这里的困境是,有时(在您的情况下),服务充当数据源,从一些长期运行的任务向UI提供数据。
那么Android架构组件中应该包含什么呢?我认为你可以把它当作生命周期观察者。因为,不管你在后台做什么,你都需要考虑LifecycleOwner的生命周期。
为什么?因为,我们通常会将其绑定到LifecycleOwner(活动/片段)
如何实现它?
>
使用您的服务类并实现LifecycleObserver接口。
当您将您的服务绑定到活动/片段
时,在您的服务类的服务连接期间,通过调用方法将您的服务添加到您的活动中,作为生命观察者。
现在,在服务类中使用一个接口来提供从服务到用户界面的回调,每次数据更改时,检查您的服务是否至少有生命周期事件创建或恢复来提供回调。
这样,我们就不需要LiveData
从服务更新到,甚至不需要ViewModel
(为什么我们需要它来服务?我们不需要配置更改来在服务生命周期中生存。VM的主要任务是在生命周期之间包含数据)。
边注:如果你认为你有长时间运行后台操作,那么考虑使用<代码>工作管理器< /代码>。使用此库后,您会觉得现在应该将服务标记为已弃用!(只是一个随机的想法)
本文向大家介绍推荐JavaScript实现继承的最佳方式,包括了推荐JavaScript实现继承的最佳方式的使用技巧和注意事项,需要的朋友参考一下 实现JavaScript继承的最简单的方式是call方法(或者apply方法)及原型链方法,但这两种方法都有缺陷,而其混合体就是很好的继承实现方式。下面举例说明: 对于类Animal来说,它有一个字段属性age及函数属性sayAge,sa
本文向大家介绍IntelliJ IDEA最佳配置(推荐),包括了IntelliJ IDEA最佳配置(推荐)的使用技巧和注意事项,需要的朋友参考一下 IntelliJ IDEA最佳配置 IntelliJ IDEA 分为两个版本:旗舰版(Ultimate)和社区版(Community)。旗舰版收费(30天免费使用时间,功能齐全);社区版(永久免费,功能简陋)。 1.安装目录结构解释 bin:容器,执行
2024.9.11 60min 一、自我介绍 二、实习 介绍数据流架构,实习做的事 用的框架、一些细节(没有技术问题) 三、项目 讲讲lazy allocation 这个操作系统有没有能应用的场景 四、c++ c++相对c的特性 c++11新特征 虚函数和纯虚函数 五、做题 反转链表 快排 六、反问 业务方向:推荐,在线c++离线Java
我试图使用Kotlin实现干净的架构。这一过程的流程将是: 代码示例:
本文向大家介绍2014年最新推荐的10款 PHP 开发框架,包括了2014年最新推荐的10款 PHP 开发框架的使用技巧和注意事项,需要的朋友参考一下 PHP去年发生了翻天覆地的变化。似乎每个人对于一个好的框架应该是什么样子都有自己的想法,但话又说回来,不同的框架适用于不同类型的项目,没有什么框架是万能的。 优秀的 PHP 框架可以帮助开发者构建干净整洁和结构化的 Web 开发,同时也加快了创建和