【问题标题】:How can I access my activity's ViewModel from within a service?如何从服务中访问我的活动的 ViewModel?
【发布时间】: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中创建构造函数

标签: android android-intent service android-service jobintentservice


【解决方案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 部分中插入什么,因为它请求和活动或片段。尝试不同的想法,但到目前为止它什么都不接受
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2019-07-29
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多