简体   繁体   English

Android服务应该在MVP模式中扮演什么角色?

[英]What role an Android Service should play in the MVP pattern?

I am developing an Android app that does Human Activity Recognition. 我正在开发一个人类活动识别的Android应用程序。

It basically works like that - Service constantly reads the accelerator data and stores the recognized activity (ie Walking, running) in a database. 它基本上就是这样 - 服务不断读取加速器数据并将识别的活动(即步行,运行)存储在数据库中。 The user can see all of the recognized activities in an ListView in activity (accesses the database). 用户可以在活动中查看ListView中的所有已识别活动(访问数据库)。 Every User table in the database has a pa_goal (physical activity goal) field which the Service reads from the database and does some checks. 数据库中的每个User表都有一个pa_goal(物理活动目标)字段,服务从数据库中读取该字段并进行一些检查。

The user, of course, can change this goal from an activity. 当然,用户可以从活动中更改此目标。 Since I will be implementing the MVP architectural pattern. 因为我将实现MVP架构模式。

I am unsure where to put the Service? 我不确定在哪里提供服务? It surely isn't View. 肯定不是View。 Any advice? 有什么建议?

In a clean architecture, which is what I am assuming you are using MVP for, there is the idea of separating the framework from the business logic. 在一个干净的架构中,我假设您正在使用MVP,这就是将框架与业务逻辑分离的想法。 This is essentially what a normal presenter allows you to do. 这基本上是普通演示者允许您做的事情。

In this case its not a view you are dealing with but the principle is similar. 在这种情况下,它不是你正在处理的观点,但原则是相似的。 You don't want all your business or application logic mixed in the Android code when you can separate them out for nicer, more single responsibility classes. 当您可以将它们分离出来以获得更好,更单一的责任类时,您不希望将所有业务或应用程序逻辑混合在Android代码中。 So I would say that while it isn't a view you should still have a presenter type class (probably better to be called controller or manager maybe). 所以我会说,虽然它不是一个视图,你仍然应该有一个演示者类型类(可能更好地称为控制器或管理器)。

This class would be a POJO that controls how your service behaves which is easily testable with standard junit tests and service mocks. 这个类将是一个POJO,它控制您的服务行为,使用标准的junit测试和服务模拟可以轻松测试。 This class and the service could then be put into its own feature package and interact with the back end models the same way as your presenters. 然后可以将此类和服务放入其自己的功能包中,并以与演示者相同的方式与后端模型进行交互。

So, in summary, the role is of another feature of your app that sites alongside the other features (which are usually just views in my experience). 因此,总而言之,该角色是您的应用的另一个功能,即网站与其他功能(通常只是我的经验中的视图)。

Hope that helps 希望有所帮助

This article helped me in a similar situation, although may not be exactly yours, the idea is the same: 这篇文章在类似的情况下帮助了我,虽然可能不完全是你的,但这个想法是一样的:

https://android.jlelse.eu/android-bound-services-and-mvp-12ca9f70c7c7 https://android.jlelse.eu/android-bound-services-and-mvp-12ca9f70c7c7

Basically, the author works around the fact that a bound service is tightly coupled to an activity, and it adds extra lifecycle calls to it. 基本上,作者围绕这样一个事实,即绑定服务与活动紧密耦合,并为其添加额外的生命周期调用。

I am in the same situation. 我处于同样的境地。 Finally I decided to do something like this: 最后我决定做这样的事情:

Activities or Fragments are out of scope, they do not know anything about MVP BUT i am going to use an event bus like Otto to send signals/events, So: 活动或片段超出范围,他们对MVP一无所知但是我将使用像Otto这样的事件总线来发送信号/事件,所以:

My classes which extends some kind of Presenter know nothing about Android Context but they will have an MvpView interface, with only onAttachPresenter and onDetachPresenter. 扩展某种Presenter的我的类对Android上下文一无所知,但它们将有一个MvpView接口,只有onAttachPresenter和onDetachPresenter。

The class which extends Service will have a Presenter attribute and implements some MvpView interface with onSucess, onError, onStart, onComplete or something like that and same events for Otto (onSucessEvent, onErrorEvent, onStartEvent, onCompleteEvent). 扩展Service的类将具有Presenter属性,并使用onSucess,onError,onStart,onComplete或类似的东西实现一些MvpView接口,以及Otto(onSucessEvent,onErrorEvent,onStartEvent,onCompleteEvent)的相同事件。

So when I need to do something the Activity or Fragment will start the service, the service will "start" or talk with the Presenter and when the presenter finish with success will call to mvpView.onSuccess() and store the info inside a local DB with SQLite (storeIO maybe) and finally the Service will invoke Otto and pass the signal (without any data on it), probably onComplete. 因此,当我需要执行某些操作时,Activity或Fragment将启动该服务,该服务将“启动”或与Presenter交谈,当演示者成功完成时将调用mvpView.onSuccess()并将信息存储在本地数据库中使用SQLite(也许是storeIO),最后服务将调用Otto并传递信号(没有任何数据),可能是onComplete。 Finally the signal will be catched by my UI (fragment maybe) and retrieve all the info inside a DB in SQLite. 最后,我的UI(可能是片段)将捕获信号,并在SQLite中检索数据库中的所有信息。

So when the onSucess happens the UI will show the latest and best data BUT when onError happens will (at least) show some info (or not if you want) saying to the user "there was a problem but at least you can see something", bot onSuccess and onError will call onComplete after all. 因此,当onSucess发生时,UI将显示最新和最佳数据但是当onError发生时将(至少)显示一些信息(或者如果你想要的话),对用户说“有问题,但至少你可以看到一些东西” ,bot onSuccess和onError毕竟会调用onComplete。

Do not know if this is the best solution but in this case I think I am not going to deal with Activities or Fragments lifecycle and do not care about onSaveInstance and restore data when the user rotates the device. 不知道这是否是最佳解决方案,但在这种情况下,我认为我不打算处理活动或碎片生命周期,也不关心onSaveInstance并在用户旋转设备时恢复数据。 It will always fetch the latest data inside DB, and if something happens (no internet connection) you can at least show something when you receive the onComplete Signal. 它总是会获取数据库中的最新数据,如果发生了某些事情(没有互联网连接),您至少可以在收到onComplete信号时显示某些内容。

Some facts I am still thinking: 我仍在思考的一些事实:

  • The Presenter won't be a singleton class 演示者不会是单身人士
  • Presenter knows nothing about Context but yes with MyApplication class Presenter对Context一无所知,但对MyApplication类一无所知
  • What happens if for one screen (Fragment) you have differents service with differents onSuccessEvents? 如果对于一个屏幕(片段),您有不同的服务与不同的onSuccessEvents会发生什么? Simply use some kind of action as an ID, to identify them. 只需使用某种操作作为ID即可识别它们。
  • Never make the Activity Fragment implements the MvpView, you will have to deal with the lifecycle. 永远不要让Activity Fragment实现MvpView,你将不得不处理生命周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM