在MediaBrowserServiceCompat

时间:2019-04-09 17:05:54

标签: android android-room android-livedata android-mediasession

我正在使用Android Architecture组件开发音频应用。我有一个服务,它扩展了MediaBrowserServiceCompat和一个带有MediaBrowserCompat的片段。

当我使用服务的onLoadChildren()方法对歌曲进行硬编码时,一切工作都很好。但是我将歌曲存储在Room数据库中,并希望以onLoadChildren()方法加载它们。这就是我在努力的地方。

我尝试通过两种方式加载歌曲:

1) SongsDAO:

@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);
 }

这样,我收到一个错误,房间查询是在主线程上执行的。一种可能的方法可能是将该方法封装到AsyncTask中,但我相信还有更好的方法。

2) SongsDAO:

@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数据库中删除任何歌曲时,列表应自动更新。

您如何建议实施类似的方法?预先感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

解决方案之一是使用observeForever(不需要生命周期所有者作为参数)而不是observe。此外,我建议使用removeobserver删除使用过的onDestroy的{​​{1}}生命周期方法内的创建的观察者,以避免内存泄漏。