Я работаю над аудиоприложением, используя компоненты архитектуры Android. У меня есть служба, которая расширяет MediaBrowserServiceCompat
и фрагмент с MediaBrowserCompat
.
Все работает очень хорошо, когда я жестко onLoadChildren()
песни в onLoadChildren()
. Но мои песни хранятся в базе данных Room и я хочу загрузить их в метод onLoadChildren()
. Вот где я борюсь.
Есть два способа загрузки песен:
1) Песни ДАО:
@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) Песни ДАО:
@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, список должен обновляться автоматически.
Как вы рекомендуете реализовать что-то подобное? Заранее спасибо за любое предложение.
Одним из решений является использование наблюдаемого (который не требует наличия владельца жизненного цикла в качестве параметра) вместо observe
. Кроме того, я рекомендовал удалить созданный наблюдатель внутри onDestroy
жизненного цикла onDestroy
использованного Service
используя removeobserver для избежания утечек памяти.