2017-10-14 49 views
0

我必須從數據庫加載緩存版本的數據,同時我想向服務器請求新鮮數據,並且我希望在每頁基礎上執行此操作。 因此,例如對於第一頁,我想要顯示來自數據庫的第一頁數據的緩存版本,而僅請求第一頁的新數據。
我想用Paging Library來實現這個。
我試圖創建自定義數據源,它幫助我攔截頁面加載請求,然後我用網頁調用所需的頁碼和限制,同時我從數據庫返回一個緩存版本,問題是在從網絡獲取新數據後我更新數據庫,但這些更新沒有反映出來。 (我相信使用Invalidation Tracker的任何修改都會觀察整個表格,並且無論何時表格無效,數據源都會失效,但我也在數據源中添加了該跟蹤器,但仍然無法使用;我能夠使指出,失效跟蹤的事情暫時創建:在JobDao LivePagedListProvider getJobs(),並檢查生成的實現)分頁庫 - 在從網絡請求時從緩存填充

代碼:

public class JobListDataSource<T> extends TiledDataSource<T> { 

private final JobsRepository mJobsRepository; 
private final InvalidationTracker.Observer mObserver; 


String query = ""; 

public JobListDataSource(JobsRepository jobsRepository) { 
    mJobsRepository = jobsRepository; 

    mObserver = new InvalidationTracker.Observer(JobEntity.TABLE_NAME) { 
     @Override 
     public void onInvalidated(@NonNull Set<String> tables) { 
      invalidate(); 
     } 
    }; 

    jobsRepository.addInvalidationTracker(mObserver); 
} 


@Override 
public int countItems() { 
    return DataSource.COUNT_UNDEFINED; 
} 

@Override 
public List<T> loadRange(int startPosition, int count) { 
    return (List<T>) mJobsRepository.getJobs(query, startPosition, count); 
} 


public void setQuery(String query) { 
    this.query = query; 
} 
} 

職位庫功能:

public List<JobEntity> getJobs(String query, int startPosition, int count) { 
    if (!isJobListInit) { 
     JobList jobList = mApiService.getOpenJobList(
       mRequestJobList.setPageNo(startPosition/count + 1) 
       .setMaxResults(count) 
       .setSearchKeyword(query) 
     ).blockingSingle(); 
     mJobDao.insert(jobList.getJobsData()); 
    } 
    return mJobDao.getJobs(startPosition, count); 
} 

public void addInvalidationTracker(InvalidationTracker.Observer observer) { 
    mAppDatabase.getInvalidationTracker().addObserver(observer); 
} 

回答

0

所以我明白了爲什麼它不能正常工作,在我的最後出現了一個錯誤,我在JobRepository中傳遞了JobJO的JOB方法的錯誤參數。

JobDao的getJobs方法去如下:

@Query("SELECT * FROM jobs ORDER BY jobID ASC LIMIT :limit OFFSET :offset") 
List<JobEntity> getJobs(int limit, int offset); 

和呼叫getJobs()在JobsRepository去如下:

return mJobDao.getJobs(startPosition, count); 

所以第一個參數是極限,下一個是抵消,但我是通過其他方式。
現在它就像一個魅力!

此外,我對JobsRepository中的getJobs()進行了更改: 首先從db中獲取數據(如果可用)返回並根據需要向網絡發出異步請求。 如果db中沒有數據可用,則調用同步調用網絡,從網絡獲取數據,解析數據並保存數據庫,然後從db中獲取最新數據並返回。 因此函數是這樣的:

//you can even refactor this code so that all the network related stuff is in one class and just call that method 
public List<JobListItemEntity> getJobs(String query, int startPosition, int count) { 
    Observable<JobList> jobListObservable = mApiService.getOpenJobList(
      mRequestJobList.setPageNo(startPosition/count + 1) 
        .setMaxResults(count) 
        .setSearchKeyword(query)); 

    List<JobListItemEntity> jobs = mJobDao.getJobsLimitOffset(count, startPosition); 

    //no data in db, make a synchronous call to network to get the data 
    if (jobs.size() == 0) { 
     JobList jobList = jobListObservable.blockingSingle(); 
     updateJobList(jobList, startPosition, false); 
    } else if (shouldFetchJobList(jobs)) { 
     //data available in db, so show a cached version and make async network call to update data as this data is no longer fresh 
     jobListObservable.subscribe(new Observer<JobList>() { 
      @Override 
      public void onSubscribe(Disposable d) { 

      } 

      @Override 
      public void onNext(JobList jobList) { 
       updateJobList(jobList, startPosition, true); 
      } 

      @Override 
      public void onError(Throwable e) { 
       Timber.e(e); 
      } 

      @Override 
      public void onComplete() { 

      } 
     }); 
    } 
    return mJobDao.getJobsLimitOffset(count, startPosition); 
} 

updateJobList()代碼:

private void updateJobList(JobList jobList, int startPosition, boolean performInvalidation) { 
    JobListItemEntity[] jobs = jobList.getJobsData(); 

    Date currentDate = Calendar.getInstance().getTime(); 

    //tracks when this item was inserted in db, used in calculating whether data is stale 
    for (int i = 0; i < jobs.length; i++) { 
     jobs[i].insertedAt = currentDate; 
    } 

    mJobDao.insert(jobs); 

    if (performInvalidation) { 
     mJobListDataSource.invalidate(); 
    } 
} 

(我也改名爲getJobs()在JobDao到getJobsLimitOffset(),因爲它使得它更具可讀性,這是也是分頁庫生成方法的方式)