Загружать элементы из комнаты в MediaBrowserServiceCompat

Я работаю над аудиоприложением, используя компоненты архитектуры Android. У меня есть служба, которая расширяет MediaBrowserServiceCompat и фрагмент с MediaBrowserCompat.

Все работает довольно хорошо, когда я жестко кодирую песни в методе службы onLoadChildren(). Но мои песни хранятся в базе данных Room, и я хотел бы загрузить их методом onLoadChildren(). Вот где я борюсь.

Есть 2 способа, как я пытался загрузить песни:

1) Песни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);
 }

Таким образом, я получаю сообщение об ошибке, что запрос комнаты был выполнен в основном потоке. Один из возможных способов, вероятно, заключается в инкапсуляции метода в AsyncTask, но я считаю, что есть и лучшие способы.

2) Песни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 (первый параметр метода наблюдения).

Я не смог найти какой-либо передовой опыт решения этого варианта использования. Я хотел бы иметь класс SPOT (единая точка истины), который содержал бы все песни в приложении. Затем его можно использовать в службе для предоставления данных пользовательскому интерфейсу приложения (RecyclerView), а также другим приложениям (Android Auto). Я хотел бы иметь доступ к этим песням из любого места в приложении — когда я добавляю новую песню или удаляю любую из базы данных Room, список должен обновляться автоматически.

Как вы рекомендуете реализовать что-то подобное? Заранее спасибо за любое предложение.


person Marek Potkan    schedule 09.04.2019    source источник


Ответы (1)


Одним из решений является использование observeForever (которое не требует владельца жизненного цикла в качестве параметра) вместо observe. Кроме того, я рекомендовал удалить созданный наблюдатель внутри onDestroy метода жизненного цикла используемого Service с помощью removeobserver для предотвращения утечек памяти.

person Valerii    schedule 09.04.2019