//远程数据源 private final TasksDataSource mTasksRemoteDataSource; //本地数据源 private final TasksDataSource mTasksLocalDataSource; //数据源监听器 privateList<TasksRepositoryObserver> mObservers = newArrayList<TasksRepositoryObserver>();
/** * 内存缓存区 */ Map<String, Task> mCachedTasks;
/** * Marks the cache as invalid, to force an update the next time data is requested. This variable * has package local visibility so it can be accessed from tests. */ //用于表示当前缓存数据是否可用 boolean mCacheIsDirty;
/** * Returns the single instance of this class, creating it if necessary. * * @param tasksRemoteDataSource the backend data source * @param tasksLocalDataSource the device storage data source * @return the {@link TasksRepository} instance */ //单例方式创建TasksRepository publicstaticTasksRepositorygetInstance(TasksDataSource tasksRemoteDataSource, TasksDataSource tasksLocalDataSource) { if (INSTANCE == null) { INSTANCE = newTasksRepository(tasksRemoteDataSource, tasksLocalDataSource); } returnINSTANCE; }
/** * Used to force {@link #getInstance(TasksDataSource, TasksDataSource)} to create a new instance * next time it's called. */ publicstaticvoiddestroyInstance() { INSTANCE = null; }
/** * * Gets tasks from cache, local data source (SQLite) or remote data source, whichever is * available first. This is done synchronously because it's used by the {@link TasksLoader}, * which implements the async mechanism. */ @Nullable @Override publicList<Task> getTasks() { List<Task> tasks = null; if (!mCacheIsDirty) { //表示缓存中数据还可以用 // Respond immediately with cache if available and not dirty if (mCachedTasks != null) { //从缓存中获取数据 tasks = getCachedTasks(); return tasks; } else { //这个是第一次的情况下,从数据库中加载数据 // Query the local storage if available. tasks = mTasksLocalDataSource.getTasks(); } } // To simplify, we'll consider the local data source fresh when it has data. //如果从本地数据库中加载完就会跑到这里,对结果进行判断,如果是空则表示,数据库中没有想要的数据,那么就从远程数据源中获取。 if (tasks == null || tasks.isEmpty()) { // Grab remote data if cache is dirty or local data not available. tasks = mTasksRemoteDataSource.getTasks(); // We copy the data to the device so we don't need to query the network next time //从远程数据源中获取后将其缓存到数据库中,供下一次使用。 saveTasksInLocalDataSource(tasks); } //不论是从数据库中加载还是从远程数据源中加载数据都需要将数据缓存到内存中 processLoadedTasks(tasks); returngetCachedTasks();
//保存任务 @Override publicvoidsaveTask(@NonNull Task task) { checkNotNull(task); mTasksRemoteDataSource.saveTask(task); mTasksLocalDataSource.saveTask(task); // Do in memory cache update to keep the app UI up to date if (mCachedTasks == null) { mCachedTasks = newLinkedHashMap<>(); } mCachedTasks.put(task.getId(), task); // Update the UI notifyContentObserver(); }
// Do in memory cache update to keep the app UI up to date if (mCachedTasks == null) { mCachedTasks = newLinkedHashMap<>(); } mCachedTasks.put(task.getId(), completedTask); // Update the UI notifyContentObserver(); }
// Do in memory cache update to keep the app UI up to date if (mCachedTasks == null) { mCachedTasks = newLinkedHashMap<>(); } mCachedTasks.put(task.getId(), activeTask);
// Do in memory cache update to keep the app UI up to date if (mCachedTasks == null) { mCachedTasks = newLinkedHashMap<>(); } Iterator<Map.Entry<String, Task>> it = mCachedTasks.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Task> entry = it.next(); if (entry.getValue().isCompleted()) { it.remove(); } }
// Update the UI notifyContentObserver(); }
/** * Gets tasks from local data source (sqlite) unless the table is new or empty. In that case it * uses the network data source. This is done to simplify the sample. */ @Override publicTaskgetTask(@NonNull final String taskId) { checkNotNull(taskId);
Task cachedTask = getTaskWithId(taskId);
// Respond immediately with cache if we have one if (cachedTask != null) { return cachedTask; }
// Is the task in the local data source? If not, query the network. Task task = mTasksLocalDataSource.getTask(taskId); if (task == null) { task = mTasksRemoteDataSource.getTask(taskId); }
//将结果传递给UI线程 if (isStarted()) { super.deliverResult(data); }
}
@Override protectedvoidonStartLoading() {
//如果缓存中有任何可用的数据那么直接返回 // Deliver any previously loaded data immediately if available. if (mRepository.cachedTasksAvailable()) { deliverResult(mRepository.getCachedTasks()); } //监听数据集的变化 // Begin monitoring the underlying data source. mRepository.addContentObserver(this);
//如果内容有改变或者内存缓存内的任务不可用那么强制执行一次加载 if (takeContentChanged() || !mRepository.cachedTasksAvailable()) { // When a change has been delivered or the repository cache isn't available, we force // a load. forceLoad(); } }
publicTasksPresenter(@NonNullTasksLoader loader, @NonNullLoaderManager loaderManager, @NonNullTasksRepository tasksRepository, @NonNullTasksContract.View tasksView) { mLoader = checkNotNull(loader, "loader cannot be null!"); mLoaderManager = checkNotNull(loaderManager, "loader manager cannot be null"); mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null"); mTasksView = checkNotNull(tasksView, "tasksView cannot be null!"); mTasksView.setPresenter(this); }
@Override publicvoidresult(int requestCode, int resultCode) { // If a task was successfully added, show snackbar if (AddEditTaskActivity.REQUEST_ADD_TASK == requestCode && Activity.RESULT_OK == resultCode) { mTasksView.showSuccessfullySavedMessage(); } }
/** * @param forceUpdate Pass in true to refresh the data in the {@link TasksDataSource} */ publicvoidloadTasks(boolean forceUpdate) { if (forceUpdate || mFirstLoad) { mFirstLoad = false; mTasksRepository.refreshTasks(); } else { showFilteredTasks(); } }
privatevoidprocessTasks(List<Task> tasks) { if (tasks.isEmpty()) { // Show a message indicating there are no tasks for that filter type. processEmptyTasks(); } else { // Show the list of tasks mTasksView.showTasks(tasks); // Set the filter label's text. showFilterLabel(); } }