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

Pra*_*anD 8 android android-viewmodel android-architecture-components

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

locationViewModel = ViewModelProviders.of(this).get(LocationViewModel.class);
locationViewModel.getLocations().observe(this, this);
Run Code Online (Sandbox Code Playgroud)

当我通过BroadCastReceiver接收位置更新时,应将定期背景位置保存到会议室数据库.他们应该通过电话保存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)
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Sag*_*gar 7

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

你不应该那样做。它的不良设计实践。

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

不,这没有帮助

您可以按以下方式实现所需的结果:

将Room DB操作与ViewModel单独的singleton类分开。在ViewModel需要的任何其他地方使用它。收到广播后,请通过此单例类而不是将数据写入DB ViewModel

如果您LiveData在Fragment 中观察,则它也会更新您的视图。

  • @PrashanD根据文档,总是与范围(片段或活动)相关联地创建ViewModel,只要范围是活动的,ViewModel就会保留。您无法使用ViewModel实现它。 (2认同)