我尝试使用自定义TiledDataSource
来使用分页库。当我使用LivePagedListProvider
类似于我的Dao方法的返回类型时,它工作正常(在更新表项后 - ui自动更新)。
@Query("SELECT * FROM " + Table.States.PLAY_STATE + ", "+Table.Chart.ARTIST+ " ORDER BY position ASC")
LivePagedListProvider<Artist> loadArtists();
但是当我尝试为TiledDataSource
表更新实现自定义LivePagerListProvider
时,没有触发我的观察者。
抽象泛型类:
public abstract class PagedNetworkBoundResource<ResultType, RequestType> extends TiledDataSource<ResultType> {
@Override
public int countItems() {
return DataSource.COUNT_UNDEFINED;
}
@Override
public List<ResultType> loadRange(int startPosition, int count) {
fetchFromNetwork(startPosition, count);
return loadFromDb(startPosition, count);
}
@WorkerThread
private void fetchFromNetwork(int startPosition, int count) {
if (createCall(startPosition, count) != null)
try {
Response<RequestType> response = createCall(startPosition, count).execute();
if (response.isSuccessful() && response.code() == 200) {
saveCallResult(response.body());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@WorkerThread
protected abstract void saveCallResult(@NonNull RequestType item);
@WorkerThread
protected abstract List<ResultType> loadFromDb(int startPosition, int count);
@WorkerThread
protected abstract Call<RequestType> createCall(int startPosition, int count);
public LiveData<PagedList<ResultType>> getAsLiveData() {
return new LivePagedListProvider<Integer, ResultType>() {
@Override
protected DataSource<Integer, ResultType> createDataSource() {
return PagedNetworkBoundResource.this;
}
}.create(0, new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPageSize(20)
.setInitialLoadSizeHint(20)
.build());
}
}
我的dao方法适用于这种情况:
@Query("SELECT * FROM " + Table.States.PLAY_STATE + ", "+Table.Chart.ARTIST+ " ORDER BY position ASC LIMIT (:limit) OFFSET (:offset)")
List<Artist> loadArtists(int offset, int limit);
我更新Table.States.PLAY_STATE
。
public void updatePlayerState(PlayerStateEntity state){
new Thread(() -> {
dao.deleteState();
dao.insertState(state);
}).run();
}
@Dao
public interface PlayStateDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertState(PlayerStateEntity playEntity);
@Query("DELETE FROM " + Table.States.PLAY_STATE)
void deleteState();
@Query("SELECT * FROM "+Table.States.PLAY_STATE)
PlayerStateEntity getPlayerState();
}
@Entity(tableName = Table.States.PLAY_STATE)
public class PlayerStateEntity extends IdEntity {
@ColumnInfo(name = "album_played_id")
private Long albumPlayedId = -1L;
@ColumnInfo(name = "track_played_id")
private Long trackPlayedId = -1L;
@ColumnInfo(name = "artist_played_id")
private Long artistPlayedId = -1L;
@ColumnInfo(name = "state")
private PlayingState state;
@ColumnInfo(name = "playing_type")
private PlayingType playingType;
public Long getAlbumPlayedId() {
return albumPlayedId;
}
public void setAlbumPlayedId(Long albumPlayedId) {
this.albumPlayedId = albumPlayedId;
}
public Long getTrackPlayedId() {
return trackPlayedId;
}
public void setTrackPlayedId(Long trackPlayedId) {
this.trackPlayedId = trackPlayedId;
}
public Long getArtistPlayedId() {
return artistPlayedId;
}
public void setArtistPlayedId(Long artistPlayedId) {
this.artistPlayedId = artistPlayedId;
}
public PlayingState getState() {
return state;
}
public void setState(PlayingState state) {
this.state = state;
}
public PlayingType getPlayingType() {
return playingType;
}
public void setPlayingType(PlayingType playingType) {
this.playingType = playingType;
}
}
class Artist extends PlayEntity{
private String name;
private String link;
private String picture;
@ColumnInfo(name = "picture_small")
private String pictureSmall;
@ColumnInfo(name = "picture_medium")
private String pictureMedium;
@ColumnInfo(name = "picture_big")
private String pictureBig;
@ColumnInfo(name = "picture_xl")
private String pictureXl;
private Boolean radio;
private String tracklist;
private Integer position;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getPictureSmall() {
return pictureSmall;
}
public void setPictureSmall(String pictureSmall) {
this.pictureSmall = pictureSmall;
}
public String getPictureMedium() {
return pictureMedium;
}
public void setPictureMedium(String pictureMedium) {
this.pictureMedium = pictureMedium;
}
public String getPictureBig() {
return pictureBig;
}
public void setPictureBig(String pictureBig) {
this.pictureBig = pictureBig;
}
public String getPictureXl() {
return pictureXl;
}
public void setPictureXl(String pictureXl) {
this.pictureXl = pictureXl;
}
public Boolean getRadio() {
return radio;
}
public void setRadio(Boolean radio) {
this.radio = radio;
}
public String getTracklist() {
return tracklist;
}
public void setTracklist(String tracklist) {
this.tracklist = tracklist;
}
public Integer getPosition() {
return position;
}
public void setPosition(Integer position) {
this.position = position;
}
@Override
public boolean isItemPlaying() {
return getId() == getArtistPlayedId().longValue() && getPlayingType() == PlayingType.Artist && getState() == PlayingState.Playing;
}
}
public abstract class PlayEntity extends PlayerStateEntity {
public abstract boolean isItemPlaying();
}
public class ArtistsRepository {
private final ChartArtistDao chartArtistDao;
private final DeezerService deezerService;
@Inject
public ArtistsRepository(ChartArtistDao chartArtistDao, DeezerService deezerService) {
this.chartArtistDao = chartArtistDao;
this.deezerService = deezerService;
}
public LiveData<PagedList<ChartArtistDao.Artist>> getArtist() {
return new PagedNetworkBoundResource<ChartArtistDao.Artist, ModelList<ChartArtistEntity>>() {
@Override
protected void saveCallResult(@NonNull ModelList<ChartArtistEntity> item) {
if (item != null) {
chartArtistDao.saveArtists(item.getItems());
}
}
@Override
protected List<ChartArtistDao.Artist> loadFromDb(int startPosition, int count) {
return chartArtistDao.loadArtists(startPosition, count);
}
@Override
protected Call<ModelList<ChartArtistEntity>> createCall(int startPosition, int count) {
return deezerService.getChartArtist(startPosition, count);
}
}.getAsLiveData();
}
}
对于每个Artist
项,我从PlayerStateEntity
添加字段(不是很好的解决方案,但这是表示ui项状态的简单方法)。在PlayerStateEntity
表更新后,Room应该通知数据更改,但是没有。
据我所知,Room不知道查询我使用的内容,也无法更新我的RecyclerView,它是通过分页库提供的。但也许有人知道如何通知Room我在我的DataSource中使用的表格以便将来触发ui更新?
答案 0 :(得分:0)
问题与自定义DataSource
实现有关。当数据发生变化时,LivePagedListProvider
应为正确的ui更新创建一个新的DataSource实例。我使用了相同的实例,所以我以前的解决方案不对。