从前台服务观察LiveData

Ily*_*sis 11 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
        })
     }
}
Run Code Online (Sandbox Code Playgroud)

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

adi*_*e49 16

我曾经ViewModelLiveDataLifecycleActivityFragments它的工作原理,并预期观察数据.

来到你的问题,当你创建 ViewModelService或任何其他Activity它会创建新实例的所有LiveData的,并且在需要其他依赖ViewModel从信息库,并最终DAO查询.如果您没有为两个ViewModel使用相同的DAO,则LiveData可能无法更新,因为它在不同的DAO实例上进行观察.

Dagger2在我的项目中使用了为DAO和其他常见依赖项维护Singleton实例.因此,您可以尝试创建Repository和DAO 单例以使其在整个Application中保持一致.

我尝试过使用ServicesLifecycleService具有相同的流量,它为我工作.

当数据从null变为pull数据时,我得到了以下输出

D/ForegroundService: onStartCommand: Resource{status=LOADING, message='null', data=null}
D/ForegroundService: onStartCommand: Resource{status=SUCCESS, message='null', data=TVShow(id=14,...
Run Code Online (Sandbox Code Playgroud)

首先它显示空数据,因为数据库中没有数据从网络中提取数据并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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不建议在服务中使用 ViewModel。请参阅[此处](https://github.com/googlesamples/android-architecture-components/issues/137) (4认同)
  • 我们是否可以不在服务中使用单例 dao 实例并更新服务中的 dao,而不是在服务中使用 viewmodel,这将自动更新 Activity 使用的 viewmodel 中的数据,从而更新 UI? (4认同)
  • 谢谢你的详细回答。我一直在使用单例,但问题是缺少 `super.onCreate()` 和 `super.onStartCommand()`。我在更新 AS 和 kotlin 插件后发现了这一点,它开始抱怨缺少调用。 (3认同)
  • @hara是的.他们不建议将它与服务一起使用,因为`Service`没有持有任何View,并且没有任何意义使用`ViewModel`作为其生命周期意识与活动和碎片等视图但我们可以使用不同的类来保存我们的`LiveData`而不是`ViewModel`,因为那些`LiveData``观察者`的`context`无论如何都是服务.因此,无需在`ViewModel`中定义它,就可以访问`LiveData` (2认同)