@Override
public void saveTask(@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 = new linkedHashMap<>();
}
mCachedTasks.put(task.getId(), task);
}
//通过taskid获取任务
@Override
public void getTask(@NonNull final String taskId, @NonNull final GetTaskCallback callback) {
checkNotNull(taskId);
checkNotNull(callback);
Task cachedTask = getTaskWithId(taskId);
// Respond immediately with cache if available
if (cachedTask != null) {
callback.onTaskLoaded(cachedTask);
return;
}
// 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 GetT
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
askCallback 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
// 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 completedTask = 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
while (it.hasNext()) {
Map.Entry
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);
}
@Override
public void deleteAllTasks() {
TASKS_SERVICE_DATA.clear();
}
@VisibleForTesting
public void addTasks(Task… tasks) {
for (Task task : tasks) {
TASKS_SERVICE_DATA.put(task.getId(), task);
}
}
}
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司19年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android学习PDF+架构视频+面试文档+源码笔记
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【算法合集】
是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司19年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
Android学习PDF+架构视频+面试文档+源码笔记
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
[外链图片转存中…(img-We2pc42a-1639559580475)]
【算法合集】
[外链图片转存中…(img-8AbHxlh4-1639559580494)]



