从前台服务观察LiveData

时间:2017-06-22 19:51:23

标签: android android-service android-livedata

我有一个存储库,用于存放LiveData对象并由两者使用 活动和通过ViewModel的前台服务。 当我开始观察活动时,一切都按预期工作。 但是,从服务中观察并不会触发观察。 这是我使用的代码

class MyService: LifecycleService() {
     lateinit var viewModel: PlayerServiceViewModel

     override fun onCreate() {
          viewModel = MyViewModel(applicationContext as Application)
     }

     override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
          viewModel.getLiveData().observe(this, Observer { data ->
            // Do something with the data
        })
     }
}

任何想法为什么它不起作用而且我没有收到数据?

1 个答案:

答案 0 :(得分:12)

我在ViewModel LiveData使用了LifecycleActivityFragments使用ViewModel,并按预期观察数据。

遇到问题,当您从Service或其他任何Activity创建 ViewModel时,会创建新实例 LiveData从存储库和最终DAO查询所需的所有LiveData和其他依赖项。 如果您没有为两个ViewModel使用相同的DAO,则Dagger2可能无法更新,因为它正在观察不同的 DAO 实例。

我在项目中使用Services来维护DAO和其他常见依赖项的Singleton实例。因此,您可以尝试使您的存储库和DAO 单例在整个应用程序中保持一致。

我尝试使用LifecycleServiceD/ForegroundService: onStartCommand: Resource{status=LOADING, message='null', data=null} D/ForegroundService: onStartCommand: Resource{status=SUCCESS, message='null', data=TVShow(id=14,... 使用相同的流程,它对我有用。

当数据从null变为pull data

时,我得到了以下输出
Observer

首先它显示了空数据,因为数据库中没有数据 从网络中提取数据并自动更新到数据库public class ForegroundService extends LifecycleService { private static final String TAG = "ForegroundService"; private TVShowViewModel tvShowViewModel; private TVShow tvShow; @Inject TVShowDataRepo tvShowDataRepo; @Override public void onCreate() { super.onCreate(); AndroidInjection.inject(this); tvShowViewModel = new TVShowViewModel(tvShowDataRepo); tvShowViewModel.init(14); } @Override public int onStartCommand(Intent intent, int flags, int startId) { tvShowViewModel.getTVShow().observe(this, tvShowResource -> { Log.d(TAG, "onStartCommand: " + tvShowResource); }); return super.onStartCommand(intent, flags, startId); } } 观察数据。

使用以下代码

完成工作
final class OverlayWindowController: NSWindowController {
  init(frame: NSRect) {
    let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false)
    super.init(window: window)

    window.contentViewController = MyViewController()
    window.backgroundColor = NSColor.clear
    window.isOpaque = false
  }

  @available(*, unavailable)
  required init?(coder: NSCoder) {
    fatalError("init(coder:) is unavailable")
  }
}