【面试必备】Android中老生常谈的三级缓存框架问题你都了解了吗

【面试必备】Android中老生常谈的三级缓存框架问题你都了解了吗,第1张

【面试必备】Android中老生常谈的三级缓存框架问题你都了解了吗

// Load from server/persisted if needed.

// Is the task in the local data source? If not, query the network.
mTasksLocalDataSource.getTask(taskId, new GetTaskCallback() {
@Override
public void onTaskLoaded(Task task) {
// Do in memory cache update to keep the app UI up to date
if (mCachedTasks == null) {
mCachedTasks = new linkedHashMap<>();
}
mCachedTasks.put(task.getId(), task);
callback.onTaskLoaded(task);
}

@Override
public void onDataNotAvailable() {
mTasksRemoteDataSource.getTask(taskId, new GetTaskCallback() {
@Override
public void onTaskLoaded(Task task) {
// Do in memory cache update to keep the app UI up to date
if (mCachedTasks == null) {
mCachedTasks = new linkedHashMap<>();
}
mCachedTasks.put(task.getId(), task);
callback.onTaskLoaded(task);
}

@Override
public void onDataNotAvailable() {
callback.onDataNotAvailable();
}
});
}
});
}
//刷新任务
@Override
public void refreshTasks() {
mCacheIsDirty = true;
}
//删除全部任务
@Override
public void deleteAllTasks() {
mTasksRemoteDataSource.deleteAllTasks();
mTasksLocalDataSource.deleteAllTasks();

if (mCachedTasks == null) {
mCachedTasks = new linkedHashMap<>();
}
mCachedTasks.clear();
}
//删除任务
@Override
public void deleteTask(@NonNull String taskId) {
mTasksRemoteDataSource.deleteTask(checkNotNull(taskId));
mTasksLocalDataSource.deleteTask(checkNotNull(taskId));

mCachedTasks.remove(taskId);
}
//从服务器获取数据
private void getTasksFromRemoteDataSource(@NonNull final LoadTasksCallback callback) {
mTasksRemoteDataSource.getTasks(new LoadTasksCallback() {
@Override
public void onTasksLoaded(List tasks) {
refreshCache(tasks);
refreshLocalDataSource(tasks);
callback.onTasksLoaded(new ArrayList<>(mCachedTasks.values()));
}

@Override
public void onDataNotAvailable() {
callback.onDataNotAvailable();
}
});
}
//刷新缓存数据
private void refreshCache(List tasks) {
if (mCachedTasks == null) {
mCachedTasks = new linkedHashMap<>();
}
mCachedTasks.clear();
for (Task task : tasks) {
mCachedTasks.put(task.getId(), task);
}
mCacheIsDirty = false;
}
//刷新本地数据库
private void refreshLocalDataSource(List tasks) {
mTasksLocalDataSource.deleteAllTasks();
for (Task task : tasks) {
mTasksLocalDataSource.saveTask(task);
}
}

}

本地数据来源类TasksLocalDataSource

public class TasksLocalDataSource implements TasksDataSource {

private static volatile TasksLocalDataSource INSTANCE;

private TasksDao mTasksDao;

private AppExecutors mAppExecutors;

// Prevent direct instantiation.
private TasksLocalDataSource(@NonNull AppExecutors appExecutors,
@NonNull TasksDao tasksDao) {
mAppExecutors = appExecutors;
mTasksDao = tasksDao;
}

public static TasksLocalDataSource getInstance(@NonNull AppExecutors appExecutors,
@NonNull TasksDao tasksDao) {
if (INSTANCE == null) {
synchronized (TasksLocalDataSource.class) {
if (INSTANCE == null) {
INSTANCE = new TasksLocalDataSource(appExecutors, tasksDao);
}
}
}
return INSTANCE;
}


@Override
public void getTasks(@NonNull final LoadTasksCallback callback) {
Runnable runnable = new Runnable() {
@Override
public void run() {
final List tasks = mTasksDao.getTasks();
mAppExecutors.mainThread().execute(new Runnable() {
@Override
public void run() {
if (tasks.isEmpty()) {
// This will be called if the table is new or just empty.
callback.onDataNotAvailable();
} else {
callback.onTasksLoaded(tasks);
}
}
});
}
};

mAppExecutors.diskIO().execute(runnable);
}


@Override
public void getTask(@NonNull final String taskId, @NonNull final GetTaskCallback callback) {
Runnable runnable = new Runnable() {
@Override
public void run() {
final Task task = mTasksDao.getTaskById(taskId);

mAppExecutors.mainThread().execute(new Runnable() {
@Override
public void run() {
if (task != null) {
callback.onTaskLoaded(task);
} else {
callback.onDataNotAvailable();
}
}
});
}
};

mAppExecutors.diskIO().execute(runnable);
}

@Override
public void saveTask(@NonNull final Task task) {
checkNotNull(task);
Runnable saveRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.insertTask(task);
}
};
mAppExecutors.diskIO().execute(saveRunnable);
}

@Override
public void completeTask(@NonNull final Task task) {
Runnable completeRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.updateCompleted(task.getId(), true);
}
};

mAppExecutors.diskIO().execute(completeRunnable);
}

@Override
public void completeTask(@NonNull String taskId) {
// Not required for the local data source because the {@link TasksRepository} handles
// converting from a {@code taskId} to a {@link task} using its cached data.
}

@Override
public void activateTask(@NonNull final Task task) {
Runnable activateRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.updateCompleted(task.getId(), false);
}
};
mAppExecutors.diskIO().execute(activateRunnable);
}

@Override
public void activateTask(@NonNull String taskId) {
// Not required for the local data source because the {@link TasksRepository} handles
// converting from a {@code taskId} to a {@link task} using its cached data.
}

@Override
public void clearCompletedTasks() {
Runnable clearTasksRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.deleteCompletedTasks();

}
};

mAppExecutors.diskIO().execute(clearTasksRunnable);
}

@Override
public void refreshTasks() {
// Not required because the {@link TasksRepository} handles the logic of refreshing the
// tasks from all the available data sources.
}

@Override
public void deleteAllTasks() {
Runnable deleteRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.deleteTasks();
}
};

mAppExecutors.diskIO().execute(deleteRunnable);
}

@Override
public void deleteTask(@NonNull final String taskId) {
Runnable deleteRunnable = new Runnable() {
@Override
public void run() {
mTasksDao.deleteTaskById(taskId);
}
};

mAppExecutors.diskIO().execute(deleteRunnable);
}

@VisibleForTesting
static void clearInstance() {
INSTANCE = null;
}
}

服务器数据来源类:FakeTasksRemoteDataSource

public class FakeTasksRemoteDataSource implements TasksDataSource {

private static FakeTasksRemoteDataSource INSTANCE;

private static final Map TASKS_SERVICE_DATA = new linkedHashMap<>();

// Prevent direct instantiation.
private FakeTasksRemoteDataSource() {}

public static FakeTasksRemoteDataSource getInstance() {
if (INSTANCE == null) {
INSTANCE = new FakeTasksRemoteDataSource();
}
return INSTANCE;
}

@Override
public void getTasks(@NonNull LoadTasksCallback callback) {
callback.onTasksLoaded(Lists.newArrayList(TASKS_SERVICE_DATA.values()));
}

@Override
public void getTask(@NonNull String taskId, @NonNull GetTaskCallback callback) {
Task task = TASKS_SERVICE_DATA.get(taskId);
callback.onTaskLoaded(task);
}

@Override
public void saveTask(@NonNull Task task) {
TASKS_SERVICE_DATA.put(task.getId(), task);
}

@Override
public void completeTask(@NonNull Task task) {
Task complet
edTask = new Task(task.getTitle(), task.getDescription(), task.getId(), true);
TASKS_SERVICE_DATA.put(task.getId(), completedTask);
}

@Override
public void completeTask(@NonNull String taskId) {
// Not required for the remote data source.
}

@Override
public void activateTask(@NonNull Task task) {
Task activeTask = new Task(task.getTitle(), task.getDescription(), task.getId());
TASKS_SERVICE_DATA.put(task.getId(), activeTask);
}

@Override
public void activateTask(@NonNull String taskId) {
// Not required for the remote data source.
}

@Override
public void clearCompletedTasks() {
Iterator> it = TASKS_SERVICE_DATA.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = it.next();
if (entry.getValue().isCompleted()) {
it.remove();
}
}
}

public void refreshTasks() {
// Not required because the {@link TasksRepository} handles the logic of refreshing the
// tasks from all the available data sources.
}

@Override
public void deleteTask(@NonNull String taskId) {
TASKS_SERVICE_DATA.remove(taskId);

entry = it.next();
if (entry.getValue().isCompleted()) {
it.remove();
}
}
}

public void refreshTasks() {
// Not required because the {@link TasksRepository} handles the logic of refreshing the
// tasks from all the available data sources.
}

@Override
public void deleteTask(@NonNull String taskId) {
TASKS_SERVICE_DATA.remove(taskId);

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5710301.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存