2017-10-17 77 views
1

を動作していないデータソースを無効:私はジョブリストにデータソース(私はページングライブラリを使用しています)と、各項目に裏打ちされたジョブのリストが保存ボタンを持っている必要がありページング図書館は最近、私はこれをしようとしていた

、および保存ボタンは、ジョブの状態を未保存から保存済み(またはその逆)からデータベースに更新し、一度更新するとデータソースが無効になります。無効化によって現在のページの再読み込みがただちに行われるはずです。

データベースの値を確認しましたが、実際には更新されましたが、UIではそうではありません。

コード:ここで

public class JobsPagedListProvider { 

private JobListDataSource<JobListItemEntity> mJobListDataSource; 

public JobsPagedListProvider(JobsRepository jobsRepository) { 
    mJobListDataSource = new JobListDataSource<>(jobsRepository); 
} 

public LivePagedListProvider<Integer, JobListItemEntity> jobList() { 
    return new LivePagedListProvider<Integer, JobListItemEntity>() { 
     @Override 
     protected DataSource<Integer, JobListItemEntity> createDataSource() { 
      return mJobListDataSource; 
     } 
    }; 
} 

public void setQueryFilter(String query) { 
    mJobListDataSource.setQuery(query); 
} 
} 

は私のカスタムデータソースである:ここで

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

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


String query = ""; 

@Inject 
public JobListDataSource(JobsRepository jobsRepository) { 
    mJobsRepository = jobsRepository; 

    mJobsRepository.setJobListDataSource(this); 

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

    jobsRepository.addInvalidationTracker(mObserver); 
} 

@Override 
public boolean isInvalid() { 
    mJobsRepository.refreshVersionSync(); 
    return super.isInvalid(); 
} 

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

が保存されていないから保存されたにジョブを更新しJobsRepositoryのコードです:ここで

public void saveJob(JobListItemEntity entity) { 
    Completable.fromCallable(() -> { 
     JobListItemEntity newJob = new JobListItemEntity(entity); 
     newJob.isSaved = true; 
     mJobDao.insert(newJob); 
     Timber.d("updating entity from " + entity.isSaved + " to " 
       + newJob.isSaved); //this gets printed in log 
     //insertion in db is happening as expected but UI is not receiving new list 
     mJobListDataSource.invalidate(); 
     return null; 
    }).subscribeOn(Schedulers.newThread()).subscribe(); 
} 

ですジョブリストのDiffingロジック:

JobRepositoryで
private static final DiffCallback<JobListItemEntity> DIFF_CALLBACK = new DiffCallback<JobListItemEntity>() { 
    @Override 
    public boolean areItemsTheSame(@NonNull JobListItemEntity oldItem, @NonNull JobListItemEntity newItem) { 
     return oldItem.jobID == newItem.jobID; 
    } 

    @Override 
    public boolean areContentsTheSame(@NonNull JobListItemEntity oldItem, @NonNull JobListItemEntity newItem) { 
     Timber.d(oldItem.isSaved + " comp with" + newItem.isSaved); 
     return oldItem.jobID == newItem.jobID 
       && oldItem.jobTitle.compareTo(newItem.jobTitle) == 0 
       && oldItem.isSaved == newItem.isSaved; 
    } 
}; 

JobListDataSource(のみ関連する部分が後述される):JobsRepositoryで

public class JobsRepository { 
//holds an instance of datasource 
private JobListDataSource mJobListDataSource; 

//setter 
public void setJobListDataSource(JobListDataSource jobListDataSource) { 
    mJobListDataSource = jobListDataSource; 
} 

} 

getJobs():jobsRepositoryで

public List<JobListItemEntity> getJobs(String query, int startPosition, int count) { 
    if (!isJobListInit) { 

     Observable<JobList> jobListObservable = mApiService.getOpenJobList(
       mRequestJobList.setPageNo(startPosition/count + 1) 
         .setMaxResults(count) 
         .setSearchKeyword(query)); 

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

     //make a synchronous network call since we have no data in db to return 
     if(jobs.size() == 0) { 
      JobList jobList = jobListObservable.blockingSingle(); 
      updateJobList(jobList, startPosition); 
     } else { 
      //make an async call and return cached version meanwhile 
      jobListObservable.subscribe(new Observer<JobList>() { 
       @Override 
       public void onSubscribe(Disposable d) { 

       } 

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

       @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) { 
    JobListItemEntity[] jobs = jobList.getJobsData(); 
    mJobDao.insert(jobs); 
    mJobListDataSource.invalidate(); 
} 
+0

をあなたのやって何のいくつかのコードを表示します。 – codeFreak

+0

あなたは 'LivePagedListProvider'を使用していますか?それは問題なしで動作します – pskink

+0

私は自分のカスタムデータソースを持っていますし、それはLivePagedListProviderです、私はいくつかのコードを投稿します、ちょうどほんわか –

答えて

0

読んだ後私がこれを実現したDataSourceのソースコード:

  1. 一度無効にされたDataSourceは、再び有効になることはありません。
  2. invalidate():invalidateが既に呼び出されている場合、このメソッドは何もしません。

JobsRepositoryで定義された)、私は実際にJobsPagedListProviderが提供する私のカスタムデータソース(JobListDataSource)のシングルトンを持っていたので、私はsaveJob()で私のDataSourceを無効にされたとき、それは最新のを取得するために(新しいDataSourceインスタンスを取得しようとしていましたデータはloadRange()を再度呼び出してデータソースをリフレッシュする方法です) 私のDataSourceはシングルトンであり、既に無効なので、loadRange()クエリが作成されていませんでした。

ですから、DataSourceのシングルトンを持っているし、あなたのDataSource手動(invalidate()を呼び出すことによって)無効にしたり、データソースのコンストラクタでInvalidationTrackerを持っていないことを確認してください。

だから、最終的な解決策は、このように書きます:

JobsPagedListProviderでシングルトンをお持ちでない:

public class JobsPagedListProvider { 

private JobListDataSource<JobListItemEntity> mJobListDataSource; 

private final JobsRepository mJobsRepository; 

public JobsPagedListProvider(JobsRepository jobsRepository) { 
    mJobsRepository = jobsRepository; 
} 

public LivePagedListProvider<Integer, JobListItemEntity> jobList() { 
    return new LivePagedListProvider<Integer, JobListItemEntity>() { 
     @Override 
     protected DataSource<Integer, JobListItemEntity> createDataSource() { 
      //always return a new instance, because if DataSource gets invalidated a new instance will be required(that's how refreshing a DataSource works)   
      mJobListDataSource = new JobListDataSource<>(mJobsRepository); 
      return mJobListDataSource; 
     } 
    }; 
} 

public void setQueryFilter(String query) { 
    mJobListDataSource.setQuery(query); 
} 
} 

はまた、あなたがネットワークからデータを取得している場合あなたが右のロジックを持っている必要がありますことを確認してくださいネットワークに問い合わせる前にデータが古くなっていないかどうかを確認します。それ以外の場合は、DataSourceが無効になるたびに再クエリーします。 JobEntityにinsertedAtフィールドを入れて、このアイテムがDBに挿入された日時を追跡して、getJobs()JobsRepositoryで古くなっているかどうかをチェックすることで解決しました。ここで

)(getJobsためのコードです:私たちは手動で無効化を処理しているよう

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 (shouldRefetchJobList(jobs)) { 
     //data available in db, so show a cached version and make async network call to update data 
     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); 
} 

最後にJobListDatasourceでInvalidationTrackerを削除します。

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

private final JobsRepository mJobsRepository; 

String query = ""; 

public JobListDataSource(JobsRepository jobsRepository) { 
    mJobsRepository = jobsRepository; 
    mJobsRepository.setJobListDataSource(this); 
} 

@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; 
} 
} 
関連する問題