25

我有一个存储库,它保存 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
        })
     }
}

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

4

1 回答 1

29

ViewModelLiveDatain一起使用LifecycleActivityFragments它按预期工作并观察数据。

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

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

我尝试使用 with ServiceswithLifecycleService和相同的流程,它对我有用。

当数据从 null 更改为提取数据时,我得到了以下输出

D/ForegroundService: onStartCommand: Resource{status=LOADING, message='null', data=null}
D/ForegroundService: onStartCommand: Resource{status=SUCCESS, message='null', data=TVShow(id=14,...

起初它显示空数据,因为数据库中不存在数据在从网络中提取数据并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);
    }
}
于 2017-08-08T15:58:52.137 回答