在Activity或Fragment之外获取ViewModel实例的正确方法

时间:2018-06-24 05:47:39

标签: android android-architecture-components android-viewmodel

我正在构建一个位置应用程序,该应用程序在MainActivity中显示Room数据库中的背景位置。我可以通过调用来获取ViewModel

locationViewModel = ViewModelProviders.of(this).get(LocationViewModel.class);
locationViewModel.getLocations().observe(this, this);

当我通过BroadCastReceiver接收位置更新时,应将周期性的背景位置保存到Room数据库中。应该通过调用locationViewModel.getLocations().setValue()

保存它们
public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {

    static final String ACTION_PROCESS_UPDATES =
            "com.google.android.gms.location.sample.backgroundlocationupdates.action" +
                    ".PROCESS_UPDATES";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_PROCESS_UPDATES.equals(action)) {
                LocationResult result = LocationResult.extractResult(intent);
                if (result != null) {
                    List<Location> locations = result.getLocations();
                    List<SavedLocation> locationsToSave = covertToSavedLocations(locations)
                    //Need an instance of LocationViewModel to call locationViewModel.getLocations().setValue(locationsToSave)
                }
            }
        }
    }
}

问题是如何在像BroadcastReceiver这样的非活动类中获取LocationViewModel实例?调用locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class)是否正确,其中context是我从BroadcastReceiver的onReceive (Context context, Intent intent)接收到的上下文?

获取ViewModel之后,由于BroadcastReceiver不是LifecycleOwner,我是否需要使用LiveData.observeForeverLiveData.removeObserver

2 个答案:

答案 0 :(得分:4)

  

问题是我应该如何在   像BroadcastReceiver这样的非活动类?

您不应该这样做。它的设计不当。

  

调用locationViewModel =是否正确?   ViewModelProviders.of(context).get(LocationViewModel.class)其中   上下文是我从onReceive接收到的上下文(上下文上下文,   Intent intent)的广播接收器?

不。没有帮助

您可以按以下步骤实现所需的结果:

在单独的单例类中将Room DB操作与ViewModel分开。在ViewModel和其他所需位置使用它。接收到广播后,通过此单例类而不是ViewModel将数据写入DB。

如果您正在观察片段中的LiveData,那么它也会更新您的视图。

答案 1 :(得分:0)

传递ViewModel实例是一种反模式。
对于您的情况,请改为传递locationViewModel.getLocations()
我不太熟悉架构组件,但在标准的Android数据绑定中,可以传递Observable*实例以设置和获取其值