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

ViewModel when implementing Room in Foreground Service

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

但是,根据文档,,到目前为止,我已经使用该服务在本地更新信息并使用 LocalBroadcasts 通知组件(这是我想使用 ViewModels 和 Observers 消除的)。

我需要服务 运行,因为应用程序需要在后台保持 运行(它是一个关键任务应用程序,应用程序关闭意味着用户将无法使用提供关键服务),并定期更新某些信息(附近请求等)。

所以要问核心问题 -

  1. 如何将服务与 ViewModel 分开,如果服务具有来自服务器的最新同步数据,我该如何更新 ViewModel 中的(可变)LiveData 列表?
  2. This article and says it is better to separate the ViewModel from the Repository while this other 一个例子给出了在 ViewModel 中包含 Room 数据库的例子。哪个更好?

我的部分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)

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

要将 ViewModel 与服务分开,请创建一个 Activity 来访问 ViewModel;您将拥有一个 Activity、一个 ViewModel 和一个服务。

这意味着您将创建绑定服务 (https://developer.android.com/guide/components/services#CreatingBoundService and, more specifically, https://developer.android.com/guide/components/bound-services)。绑定服务提供了一个接口,Activity 可以使用该接口与服务进行交互。

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

在您的实例中,该服务的任务是生成数据并将该数据传输到 Activity,后者随后将该数据提供给 ViewModel。

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

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

Activity 在收到数据后,将使用数据更新 ViewModel。任何注册到 ViewModel 的观察者都会收到最新的数据。

2)

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