在android中的服务中访问viewModel

Ima*_*ian 19 service android mvvm repository-pattern viewmodel

我们如何在服务中初始化viewModel。在片段中,我们使用 Kotlin 委托“ by ActivityViewModels ”来完成此操作。或者我们可以使用ViewModelProvider().get来完成。但据我发现,我们无法在服务中执行此操作,因为我们需要一个“ ViewModelStoreOwner ”之类的活动或片段。

那么这是否是在服务中初始化 ViewModel 的最佳实践呢?

我的项目在这里

Sau*_*rat 17

不建议在服务中使用 ViewModel。您可以从服务本身调用存储库。

https://github.com/android/architecture-components-samples/issues/137#issuecomment-327854042

ViewModel 应与 Activity 或 Fragment 紧密结合使用,因此它注定位于应用程序的 UI 层中。因此,我不建议在 Service 中使用 ViewModel。创建一个不同的类,该类将在服务中使用,如果需要,也可在 ViewModel 中使用。这样,您可以确保关注点分离,并避免赋予 ViewModel 更多所需的职责。


Yes*_*ssy 5

定义一个基础服务,然后你可以使用ViewModel,比如activity/fragment

public class LifecycleAndViewStoreOwnerService extends LifecycleService implements ViewModelStoreOwner, HasDefaultViewModelProviderFactory {

    final ViewModelStore mViewModelStore = new ViewModelStore();
    ViewModelProvider.Factory mFactory;

    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        return mViewModelStore;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                if (source.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
                    mViewModelStore.clear();
                    source.getLifecycle().removeObserver(this);
                }
            }
        });
    }

    @NonNull
    @Override
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        return mFactory != null ? mFactory : (mFactory = new ViewModelProvider.AndroidViewModelFactory(getApplication()));
    }
}
Run Code Online (Sandbox Code Playgroud)

扩展上面的类,在服务中显示一个覆盖窗口

public class MyLifecycleService extends LifecycleAndViewStoreOwnerService {

    private static final String TAG = "MyLifecycleService";

    @Override
    public void onCreate() {
        super.onCreate();
        final OverlayWindowBinding binding = OverlayWindowBinding.inflate(LayoutInflater.from(this));
        binding.setViewModel(new ViewModelProvider(this).get(ViewModel.class));
        binding.setLifecycleOwner(this);

        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        getSystemService(WindowManager.class).addView(binding.getRoot(), layoutParams);

        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                if (source.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
                    getSystemService(WindowManager.class).removeViewImmediate(binding.getRoot());
                    source.getLifecycle().removeObserver(this);
                }
            }
        });
    }

    public static class ViewModel extends AndroidViewModel {
        public ViewModel(@NonNull Application application) {
            super(application);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)