在 Repository class 中观察永远是一个好习惯吗? db+网络分页列表

Is it a good practice to observeForever in Repository class? db+network paged list

我正在构建一个遵循架构 guidelines.Implemented 房间数据库缓存 + network.Need 以从单独的实体获取最新页码的应用程序。

我的模特:

@Entity(tableName = "top_rated_movie_page")
public class Top_Rated_Movies_Page {

@PrimaryKey(autoGenerate = true)
private int db_id;
private Integer page;
private Integer total_results;
private Integer total_pages;
@Ignore
private List<Result> results;
...

Result class 包含我在分页列表中显示的数据,该列表观察数据库的变化。

使用 PagedList.BoundaryCallback 我需要从网络获取新数据并将其插入数据库。 但我需要以某种方式获取页码。 我的道:

@Insert
void insertAll(Top_Rated_Movies_Page page,List<Result> top_rated_results);

@Query("SELECT * FROM Result")
DataSource.Factory<Integer, Result> getAllResults();

@Query("SELECT * FROM top_rated_movie_page WHERE page= (SELECT MAX(page) FROM top_rated_movie_page)")
LiveData<Top_Rated_Movies_Page> getMoviePage();

我正在考虑从我的存储库 class 中的数据库观察 Top_Rated_Movies_PageobserveForever() 以获得该页码。 这是解决这个问题的最好方法吗?

由于您唯一一次读取下一页键或更新后备数据库是通过 BoundaryCallback,您可以直接读取/写入下一页键。

所以在你的 onItemAtEndLoad() 实现中你想要这样的东西:

String nextMoviePage = db.runInTransaction(() -> {
    movieDao.nextRemoteKey().key;
});

// Make sure not to run on main thread
MovieNetworkResponse response = networkApi.fetchNextMoviePage(remoteKey);

db.runInTransaction(() -> {
    movieDao.clearAll(); // Remove previous key
    movieDao.insertKey(RemoteKey(response.nextPageKey)); // Insert new key
    movieDao.insertAll(response.movies); // Update DataSource + invalidate()
});

你的 DAO:

@Insert
void insertAll(List<Result> top_rated_results);

@Query("SELECT * FROM Result")
DataSource.Factory<Integer, Result> getAllResults();

@Query("SELECT * FROM result_key LIMIT 1")
String nextRemoteKey();

@Insert
void insertKey(RemoteKey remoteKey);

并且不要忘记在您希望刷新数据时清除项目和 remoteKey!

如果您想跟踪查询的不同键,只需将该列添加到您的 RemoteKey 实体即可。

仅供参考:Paging2 已被 Paging3 取代(尽管刚刚推出 alpha01),这里是类似的 Paging3 示例,它完全解决了您的用例:https://github.com/android/architecture-components-samples/blob/master/PagingWithNetworkSample/app/src/main/java/com/android/example/paging/pagingwithnetwork/reddit/repository/inDb/PageKeyedRemoteMediator.kt