在 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_Page
和 observeForever()
以获得该页码。
这是解决这个问题的最好方法吗?
由于您唯一一次读取下一页键或更新后备数据库是通过 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
我正在构建一个遵循架构 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_Page
和 observeForever()
以获得该页码。
这是解决这个问题的最好方法吗?
由于您唯一一次读取下一页键或更新后备数据库是通过 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