0

Ich habe versucht, benutzerdefinierte TiledDataSource für die Verwendung mit Paging-Bibliothek zu implementieren. Als ich LivePagedListProvider wie Rückgabetyp für meine Dao-Methode verwendete, funktionierte es gut (nach Aktualisierung der Tabellenelemente - ui wurde automatisch aktualisiert).Benutzerdefinierte TiledDataSource mit Paging-Bibliothek

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

Aber wenn ich versuche, implementieren benutzerdefinierte TiledDataSource für LivePagerListProvider Tabellenaktualisierungen meine Beobachter nicht ausgelöst.

Abstrakte generische Klasse:

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

Meine dao Methode für diesen Fall:

@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); 

I Table.States.PLAY_STATE aktualisieren.

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

Für jede Artist Artikel I Felder hinzufügen aus PlayerStateEntity (nicht gute Lösung, aber diese einfache Art und Weise Zustand ui Elemente darzustellen). Nach PlayerStateEntity Tabelle Updates Zimmer sollte über Datenänderungen informieren, tut es aber nicht.

Ich verstehe, dass Zimmer nicht über Abfrage wissen, was ich verwendet habe, und kann nicht meine RecyclerView aktualisieren, die durch Paging-Bibliothek zur Verfügung stellen. Aber vielleicht weiß jemand, wie man Room über Tabellen benachrichtigen kann, die ich in meiner DataSource für zukünftige Auslösung von Updates verwendet habe?

+0

Wie sehen ''table updates' 'aus? – pskink

+0

@pskink Ich habe meine Frage aktualisiert. Vielen Dank. – Alex

+1

Ich kann immer noch 'loadFromDb' Implementierung nicht sehen, aber werfen Sie einen Blick auf' RoomDatabase # getInvalidationTracker() 'und' DataSource # invalidate() ' – pskink

Antwort

0

Das Problem wurde mit benutzerdefinierten DataSource Realisierung in Verbindung gebracht. Wenn sich die Daten geändert haben, sollte LivePagedListProvider eine neue DataSource-Instanz für die Aktualisierung auf die richtige Version erstellen. Ich habe dieselbe Instanz verwendet, daher ist meine vorherige Lösung nicht richtig.

Verwandte Themen