私は、Android アーキテクチャ コンポーネントを使用してオーディオ アプリに取り組んでいます。拡張するサービスMediaBrowserServiceCompat
と、フラグメントを使用していMediaBrowserCompat
ます。
onLoadChildren()
サービスのメソッドで曲をハードコーディングすると、すべてがうまく機能します。onLoadChildren()
しかし、自分の曲を Room データベースに保存しており、それらをメソッドにロードしたいと考えています。これは私が苦労しているところです。
曲をロードしようとした方法は2つあります。
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);
}
このようにすると、ルームクエリがメインスレッドで実行されたというエラーが発生します。考えられる方法の 1 つは、おそらくメソッドを 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 (observe メソッドの最初のパラメーター) として使用できるものがないため、それらはループで反復できず、おそらく監視もされません。
このユース ケースを解決するためのベスト プラクティスは見つかりませんでした。アプリ内のすべての曲を含む SPOT (Single Point of Truth) クラスが必要です。その後、サービスで使用して、アプリの UI (RecyclerView) や他のアプリ (Android Auto) にデータを提供できます。アプリのどこからでもこれらの曲にアクセスできるようにしたいと考えています。新しい曲を追加したり、Room データベースから曲を削除したりすると、リストが自動的に更新されます。
このようなものをどのように実装することをお勧めしますか? ご提案いただきありがとうございます。