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

标签 android android-architecture-components android-viewmodel

我正在构建一个定位应用程序,我在其中显示来 self 的 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 这样的非 Activity 类中获取 LocationViewModel 实例?调用 locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class) 是否正确,其中 context 是我从 onReceive (Context context, Intent intent) 收到的上下文> BroadcastReceiver 的?

拿到ViewModel后,还需要用LiveData.observeForever吗?和 LiveData.removeObserver因为 BroadcastReceiver 不是 LifecycleOwner?

最佳答案

Question is how should I get the LocationViewModel instance in a non-activity class like this BroadcastReceiver?

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

Is it correct to call locationViewModel = ViewModelProviders.of(context).get(LocationViewModel.class) where context is the context that I receive from onReceive (Context context, Intent intent) of the BroadcastReceiver?

没有。没用的

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

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

如果您正在观察 fragment 中的 LiveData,那么它也会更新您的 View 。

关于android - 在 Activity 或 Fragment 之外获取 ViewModel 实例的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51007271/

相关文章:

android - 如何在我的 View 模型中重试请求

Android PagedList 更新

android - ViewModel 观察到每个回 fragment

android - 如何在 gradle 中创建动态 url?

java - 添加动画时 Android 应用程序停止

Android:SaveState、Fragments 和 ViewModel:我做错了什么?

android - 定期工作请求未在工作管理器中执行 doWork

android - 如何防止ViewModel再次触发我的加载栏

java - 使用 facebook graph api 共享链接后,Android 解析 facebook 登录不起作用。

java - 如何使用 loadDataWithBaseURL 播放嵌入视频