在前景服务中实现Room时的ViewModel

时间:2018-07-23 19:41:36

标签: android mvvm android-service android-viewmodel

我目前有一个应用程序,该应用程序具有用于所有服务器/ API交互的ForegroundService,以及一个用于本地持久性的Room数据库。我一直在尝试实现AndroidViewModel来帮助实现数据持久性和快速的UI刷新。

但是,根据文档ViewModels can't be implemented in Services,到目前为止,我已经使用Service在本地更新信息并使用LocalBroadcasts通知组件(这是我要使用ViewModels和Observers消除的功能)。

我需要让该服务运行,因为该应用需要在后台继续运行(它的关键任务应用,并且该应用已关闭,这意味着用户将无法提供关键服务),并在定期(附近的请求等)。

所以要问核心问题-

  1. 如何将服务与ViewModel分开,并且如果服务具有来自服务器的最新同步数据,如何更新ViewModel中的(可变)LiveData列表?
  2. This articlethis answer to a question here on SO表示最好将ViewModel与存储库分开,而this other给出了一个将Room数据库包含在ViewModel中的示例。哪个更好的选择?

我的某些ViewModel代码如下:

 public class HouseCallViewModel extends AndroidViewModel {

        private String TAG = HouseCallViewModel.class.getSimpleName();

        private MutableLiveData<List<HouseCall>> housecallList;
        private MutableLiveData<List<HouseCall>> openHousecalls, confirmedHousecalls, closedHousecalls, missedHousecalls, userCancelledHousecalls, respCancelledHousecalls;
        private MutableLiveData<List<Incident>> incidentList, openIncidents;
        private MutableLiveData<List<Incident>> closedIncidents, usercancelIncidents, respcancelIncidents;
        RevivDatabase database;
        Context context;


        public HouseCallViewModel(Application application) {
            super(application);

            //      DANGER WILL ROBINSON                                            
            context = application.getApplicationContext();
            database = Room.databaseBuilder(this.getApplication(),
                    RevivDatabase.class, application.getResources().getString(R.string.database)).build();
        }
        public LiveData<List<HouseCall>> getHousecallList() {
                if (housecallList == null) {
                    housecallList = new MutableLiveData<>();
                    loadHousecalls(); // need to call API and sync
                }
                return housecallList;
            }
       public LiveData<List<HouseCall>> getIncidentList() {
                    if (incidentList == null) {
                        incidentList = new MutableLiveData<>();
                        loadIncidents(); // need to call API and sync
                    }
                    return housecallList;
                }

    // other constructors, getters and setters here, and functions to update the data
    }

1 个答案:

答案 0 :(得分:2)

1)

由于您没有提供有关服务及其相关组件的代码详细信息,因此此答案是抽象的。

要从服务中分离ViewModel,请创建一个将访问ViewModel的Activity;您将拥有一个Activity,一个ViewModel和一个Service。

这意味着您将创建绑定的服务(https://developer.android.com/guide/components/services#CreatingBoundService,更具体地说是https://developer.android.com/guide/components/bound-services)。绑定的服务提供了一个接口,活动可以使用该接口与该服务进行交互。

绑定服务的一个很好的例子是Google的位置更新服务:https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService/app/src/main/java/com/google/android/gms/location/sample/locationupdatesforegroundservice

在您的实例中,服务将负责原始数据并将该数据传输到活动,然后该活动将数据提供给ViewModel。

要将数据从服务传输到ViewModel,建议使用Greenrobot的EventBus(http://greenrobot.org/eventbus/documentation/how-to-get-started/)。

每当您希望服务将数据传输到ViewModel时,对服务中的EventBus的单行调用都会将数据传输到Activity中正在侦听该类型数据的订阅服务器。

Activity在收到数据后,将使用数据更新ViewModel。然后,向ViewModel注册的所有观察者都将收到最新数据。

2)

关注点分离原则有利于将ViewModel与存储库分离。 ViewModel应该只关注将要显示给用户的数据状态,并在配置更改时保持这种状态。