我正在使用Android架构组件处理音频应用。我有一个服务,它扩展MediaBrowserServiceCompat
和片段与MediaBrowserCompat
。
当我在服务的onLoadChildren()
方法中对歌曲进行硬编码时,一切都运行良好。但我将我的歌曲存储在Room数据库中,并希望在onLoadChildren()
方法中加载它们。这是我在努力的地方。
我尝试加载歌曲的方法有两种:
1) songs DAO:
@Query("SELECT * FROM songs ORDER BY name COLLATE UNICODE ASC")
List<Song> getSongs();
服务:
@Override
public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
result.detach();
songsRepository = new SongsRepository(getApplication());
List<Song> songs = songsRepository.getSongs();
List<MediaBrowserCompat.MediaItem> mediaItems = convertToMediaItems(songs);
result.sendResult(mediaItems);
}
通过这种方式,我得到一个错误,即在主线程上执行了Room查询。一种可能的方法是将方法封装到AsyncTask中,但我相信有更好的方法。
2) songs DAO:
@Query("SELECT * FROM songs ORDER BY name COLLATE UNICODE ASC")
LiveData<List<Song>> getSongs();
服务:
@Override
public void onLoadChildren(@NonNull String parentId, @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
result.detach();
songsRepository = new SongsRepository(getApplication());
LiveData<List<Song>> songs = songsRepository.getSongs();
songs.observe(???, (Observer<List<Song>>) songs1 -> {
List<MediaBrowserCompat.MediaItem> mediaItems = mapToMediaItems(songs1);
result.sendResult(mediaItems);
});
}
这样,我不知道如何处理LiveData歌曲。它们不能在循环中迭代,也可能没有观察到,因为没有什么可以用作LifecycleOwner(observe方法的第一个参数)。
我找不到任何关于如何解决这个用例的最佳实践。我想有一个SPOT(单点真相)类,它将包含应用程序中的所有歌曲。然后可以在服务中使用它来向应用程序的UI(RecyclerView)以及其他应用程序(Android Auto)提供数据。我希望能够从应用程序的任何位置访问这些歌曲 - 当我添加新歌曲或从Room数据库中删除任何歌曲时,列表应该自动更新。
你怎么建议实现这样的东西?提前感谢任何建议。
其中一个解决方案是使用observeForever(不需要生命周期所有者作为参数)而不是observe
。此外,我建议使用onDestroy
删除使用Service
的removeobserver生命周期方法中创建的观察者,以避免内存泄漏。