首页 > 系统 > Android > 正文

Android 官方示例:android-architecture 学习笔记(三)之todo-mvp-loaders

2019-11-09 17:25:45
字体:
来源:转载
供稿:网友

项目地址:https://github.com/googlesamples/android-architecture/tree/todo-mvp-loaders/

项目结构

本项目基于todo-mvp(后文所说”对比之前的项目”,即是说的它),并使用Loaders机制来获取数据,如图: 这里写图片描述 图示,P通过Loaders获取数据M 本文MVP相关的就不再重复解释了

data模块

这里写图片描述 对比之前的项目,多了两个类: TaskLoader —— 获取一条Task数据的Loader TasksLoader —— 获取一个List<Task>数据的Loader

TasksLoader分析

引用一段官方关于Loaders的中文解释:

Android 3.0 中引入了加载器(即Loaders),支持轻松在 Activity 或片段中异步加载数据。 加载器具有以下特征:

可用于每个 Activity 和 Fragment。 支持异步加载数据。 监控其数据源并在内容变化时传递新结果。 在某一配置更改后重建加载器时,会自动重新连接上一个加载器的游标。 因此,它们无需重新查询其数据。

TasksLoader完整源码

public class TasksLoader extends AsyncTaskLoader<List<Task>> implements TasksRepository.TasksRepositoryObserver{ PRivate TasksRepository mRepository; public TasksLoader(Context context, @NonNull TasksRepository repository) { super(context); checkNotNull(repository); mRepository = repository; } @Override public List<Task> loadInBackground() { return mRepository.getTasks(); } @Override public void deliverResult(List<Task> data) { if (isReset()) { return; } if (isStarted()) { super.deliverResult(data); } } @Override protected void onStartLoading() { // 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(); } } @Override protected void onStopLoading() { cancelLoad(); } @Override protected void onReset() { onStopLoading(); mRepository.removeContentObserver(this); } @Override public void onTasksChanged() { if (isStarted()) { forceLoad(); } }}

分析如上代码: a. TasksLoader继承了AsyncTaskLoader,并实现TasksRepository.TasksRepositoryObserver接口 b. 结合LoaderManager、Loader、AsyncTaskLoader源码(这里就不全贴了)与官方文档,可分析出几个重写方法的调用周期: onStartLoading —— 开始加载数据 loadInBackground —— 在后台加载数据,即异步线程 deliverResult —— 加载完成数据后,进行分发,通过追源码,其实就是在Loader中定义了一个回调接口,可以用于处理 onStopLoading —— 停止加载数据 onReset —— 当需要回收destroy时,由LoaderManger调用 c. onStartLoading() 代码解释:如果数据仓库中缓存了数据,则直接分发;注册数据改变的观察接口;若数据改变 或 首次加载未缓存时,调用forceLoad() d. forceLoad() 调用 AsyncTaskLoader#onForceLoad(),从而开始数据异步加载任务

tasks模块分析

接下来挑一个业务模块分析一下(其它模块大同小异),比如tasks TasksPresenter主要代码:

public class TasksPresenter implements TasksContract.Presenter, LoaderManager.LoaderCallbacks<List<Task>> { private final static int TASKS_QUERY = 1; private final TasksRepository mTasksRepository; private final TasksContract.View mTasksView; private final TasksLoader mLoader; private final LoaderManager mLoaderManager; private List<Task> mCurrentTasks; private TasksFilterType mCurrentFiltering = TasksFilterType.ALL_TASKS; private boolean mFirstLoad; public TasksPresenter(@NonNull TasksLoader loader, @NonNull LoaderManager loaderManager, @NonNull TasksRepository tasksRepository, @NonNull TasksContract.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 public void start() { mLoaderManager.initLoader(TASKS_QUERY, null, this); } @Override public Loader<List<Task>> onCreateLoader(int id, Bundle args) { mTasksView.setLoadingIndicator(true); return mLoader; } @Override public void onLoadFinished(Loader<List<Task>> loader, List<Task> data) { mTasksView.setLoadingIndicator(false); mCurrentTasks = data; if (mCurrentTasks == null) { mTasksView.showLoadingTasksError(); } else { showFilteredTasks(); } } private void showFilteredTasks() { List<Task> tasksToDisplay = new ArrayList<>(); if (mCurrentTasks != null) { for (Task task : mCurrentTasks) { switch (mCurrentFiltering) { case ALL_TASKS: tasksToDisplay.add(task); break; case ACTIVE_TASKS: if (task.isActive()) { tasksToDisplay.add(task); } break; case COMPLETED_TASKS: if (task.isCompleted()) { tasksToDisplay.add(task); } break; default: tasksToDisplay.add(task); break; } } } processTasks(tasksToDisplay); }}

在start()中,

mLoaderManager.initLoader(TASKS_QUERY, null, this);

初始化了LoaderManager,则会调用

@Override public Loader<List<Task>> onCreateLoader(int id, Bundle args) { mTasksView.setLoadingIndicator(true); return mLoader; }

mLoader就被mLoaderManager所管理 当TasksLoader的加载任务开始后,会调用TasksLoader#loadInBackground():

public List<Task> loadInBackground() { return mRepository.getTasks(); }

至此,数据加载流程就分析完了。然后再交由View来显示就是了

而TasksRepository(M,不由P直接操作)、TasksLoader(由P直接操作,它再去操作TasksRepository)、TasksFragment(V)、TasksPresenter(P),都在Activity中进行初始化


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表