首页 > 解决方案 > 在 Activity 或 Fragment 之外获取 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)调用where context 是我从onReceive (Context context, Intent intent)BroadcastReceiver接收的上下文是否正确?

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

标签: androidandroid-architecture-componentsandroid-viewmodel

解决方案


问题是我应该如何在像这个 BroadcastReceiver 这样的非活动类中获取 LocationViewModel 实例?

你不应该那样做。其糟糕的设计实践。

调用 locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class) 是否正确,其中 context 是我从 BroadcastReceiver 的 onReceive (上下文上下文,意图意图)接收的上下文?

不,这无济于事

您可以通过以下方式实现您想要的结果:

将您的 Room DB 操作与ViewModel单独的单例类分开。ViewModel在需要的任何其他地方使用它。当接收到 Broadcast 时,通过这个单例类而不是ViewModel.

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


推荐阅读