0

페이징 라이브러리와 함께 사용하기 위해 사용자 정의 TiledDataSource을 구현하려고했습니다. 내 Dao 메서드에 대해 LivePagedListProvider과 같은 반환 형식을 사용하면 테이블 항목을 업데이트 한 후에 자동으로 업데이트됩니다.페이징 라이브러리가있는 사용자 정의 TiledDataSource

@Query("SELECT * FROM " + Table.States.PLAY_STATE + ", "+Table.Chart.ARTIST+ " ORDER BY position ASC") 
LivePagedListProvider<Artist> loadArtists(); 

하지만 사용자 정의 TiledDataSourceLivePagerListProvider 표 업데이트 내 관찰자를 트리거되지 구현하려고 할 때.

추상 제네릭 클래스 :이 경우에 대한

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를 업데이트합니다. 내가 PlayerStateEntity (좋지 않은 솔루션하지만 UI 항목의 상태를 표현하는이 쉬운 방법)의 필드를 추가하는 각 Artist 항목의

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(); 
    } 
} 

. PlayerStateEntity 테이블 업데이트 이후에 방은 데이터 변경 사항에 대해 알려야하지만하지는 않습니다.

방이 내가 사용한 것에 대해 알지 못하고 페이징 라이브러리에서 제공하는 RecyclerView를 업데이트 할 수 없다는 것을 알고 있습니다. 하지만 어쩌면 어떤 사람이 미래에 ui 업데이트를 트리거하기 위해 내가 DataSource 내에서 사용한 테이블에 대해 어떻게 알리는 지 알고있을 것입니다.

+0

"테이블 업데이트"는 어떻게 생겼습니까? – pskink

+0

@pskink 질문을 업데이트했습니다. 감사. – Alex

+1

여전히'loadFromDb' 구현을 볼 수는 없지만'RoomDatabase # getInvalidationTracker()'와'DataSource # invalidate()'를보십시오 – pskink

답변

0

문제는 맞춤 DataSource 실현과 관련이 있습니다. 데이터가 변경되면 LivePagedListProvider은 오른쪽 업데이트를 위해 새 DataSource 인스턴스를 만들어야합니다. 같은 인스턴스를 사용했기 때문에 이전 솔루션이 올바르지 않습니다.