如何从服务中访问我的活动的 ViewModel?

Posted

技术标签:

【中文标题】如何从服务中访问我的活动的 ViewModel?【英文标题】:How can I access my activity's ViewModel from within a service? 【发布时间】:2020-03-09 13:42:01 【问题描述】:

我正在构建一个需要检测照片中某些对象的应用。我首先将所有要检查的照片加载并保存到我的房间数据库中,并使用 ViewHolder 将其连接到我的视图。 当用户单击一个按钮时,我希望检测过程开始,并且我想为此使用 jobIntentService(因为那里可能有数千张照片)。

我的问题是 - 我如何从服务中访问视图持有者?我既需要它来实际获取文件,也需要在检测完成后更新每个文件的记录。 我试图要求将活动作为属性之一,但我收到此错误

Unable to instantiate service tech.levanter.anyvision.services.DetectJobIntentService: java.lang.InstantiationException: java.lang.Class<tech.levanter.anyvision.services.DetectJobIntentService> has no zero argument constructor

不胜感激,谢谢

【问题讨论】:

你必须在DetectJobIntentService中创建构造函数 【参考方案1】:

ViewModel 对活动和片段具有特别重要的意义(例如,它们在配置更改期间保留数据)。所以服务并不真正需要它。因此,您可以通过以下两种方式之一解决此问题。

方法一:

如果您的 MyViewModel 只是用于从您的 Repository 类访问 LiveData 的包装器,那么您可以在您的服务中使用您的 Repository 类。

方法二:

如果您的 ViewModel 不仅仅是包装对 Repository 的调用,并且您希望您的 Service 类能够访问 ViewModel 中定义的相同逻辑,那么请使用中间 ViewModelContent 类。不要将所有内容都放在 MyViewModel 类中,而是将它们放在“ViewModelContent”类中。然后使用您的 MyViewModel 类作为 ViewModelContent 的访问器包装器。然后,您的 Service 可以像实例化任何其他类一样实例化 ViewModelContent。

class MyViewModel(application: Application) : androidViewModel(application) 
   init
      viewModelContent = ViewModelContent(...) 
   

方法 1 通常比 方法 2 更干净。

【讨论】:

如果遵循此方法对您不起作用,请在您的帖子中包含您的 ViewModel 代码,以便我们查看导致问题的原因。 但是对于哪个所有者?当像 ViewModelProviders.of(it).get(AllPhotosViewModel::class.java) 这样启动 viewHolder 时,我在 of 下放置了什么值。我使用我的 viewHolder 与存储库通信,该存储库又与我的数据库通信,并且应该根据我的服务中运行的操作更改项目。 就个人而言,我会使用 LocalBroadcastManager 将意图发送到片段/活动,如果我们仍在使用该片段,那么我们会将其拾取并将其推送到当前视图模型中(作为 viewModel有一个fragments生命周期的生命周期 @Brandon,谢谢,我会调查的。你能建议如何访问 viewModel 吗?我需要访问它以与存储库和数据库交互,但不知道在if 部分中插入什么,因为它请求和活动或片段。尝试不同的想法,但到目前为止它什么都不接受

以上是关于如何从服务中访问我的活动的 ViewModel?的主要内容,如果未能解决你的问题,请参考以下文章

每秒从服务访问数据到地图活动

如何在 viewmodel 中访问 mvvm 模型中的控件?

我的活动中的 ViewModel.Observe() 函数没有触发

如何从 viewmodel 访问用户控件上的命令

访问 Recycler´s Adapter 中的 ViewModel

从通知意图启动活动时重新创建 Android ViewModel