深入源码解析Android中Loader、AsyncTaskLoader、CursorLoader、

如果对Loader、AsyncTaskLoader、CursorLoader、LoaderManager等概念不明白或不知道如何使用Loader机制,可参见博文Android中Loader及LoaderManager的使用(附源码下载)。本文主要通过研究Loader及其子类的生命周期的方式来对Loader及其子类、LoaderManager的源码进行研究。

Loader是靠LoaderManager管理的,LoaderManager可以同时管理多个Loader,即LoaderManager与Loader是一对多的关系。我们是在Activity或Fragment使用Loader的,虽然Loader有很多public方法,但是我们不能直接调用Loader的这些public方法,因为这会扰乱LoaderManag对Loader的正常管理,我们应该通过LoaderManager的initLoader以及restartLoader方法间接管理Loader,并通过LoaderCallbacks的回调方法(onCreateLoader、onLoadFinished、onLoaderReset)对数据进行相应处理。

Loader本身不具备异步加载数据的能力;AsyncTaskLoader继承自Loader,通过AsyncTask可以异步加载数据;CursorLoader继承自AsyncTaskLoader,可以异步加载Cursor数据。

我们是在Activity或Fragment使用Loader的,Activity、Fragment与LoaderManagement交互类似于client-server模式,即Activity或Fragment是该client-server模型中的client端,即客户端,在本文中,我们所提到的客户端均指的是Loader的使用者,即Activity或Fragment。

概括来说,Loader有两大生命周期: active 和 inactive,即活动状态和非活动状态。这一点在LoaderManager的源码中体现的很直观: LoaderManager内部有两个数组mLoaders和mInactiveLoaders,其中mLoaders存储着所有处于active状态的Loader,mInactiveLoaders存储着所有处于inactive状态的Loader。

细分来说,Loader的active状态又分为started状态和stopped状态,即启动状态和停止状态,注意,stopped状态也是active生命周期的。Loader的inactive状态又分为abandoned状态和reseted状态,即废弃状态和重置状态,其中abandoned状态表明Loader现在已经废弃了,过段时间也会被重置,reseted状态表明该Loader完全被销毁重用了。Loader活跃度从高到低依次为 started -> stopped -> abandoned -> reseted,这也对应着Loader的四个生命周期,Loader处于started状态时最活跃,Loader处于reseted状态时完全不活跃。实际上,处于stopped状态的Loader也有可能再次转变为started状态,所以我们要稍将上面started到stopped之间单向箭头改为双向箭头,即Loader准确的生命周期应该是 started <-> stopped -> abandoned -> reseted。

以下是对Loader及其子类各生命周期中源码调用过程的分析,需要说明的是,由于AsyncLoader继承自Loader、CursorLoader继承自AsyncLoader,所以我们在分析代码时,这三个类都会涉及,因为子类可以实现或重写父类的方法,比如Loader类自身有个空的方法onStartLoading(),AsyncLoader没有重写该方法,但是CursorLoader重写了Loader中的空方法onStartLoading()从而CursorLoader在该方法中实现自己的逻辑。

需要注意的是,LoaderManager是个抽象类,Android有一个类LoaderManagerImpl实现了LoaderManager,Activity或Fragment中通过getLoaderManager()方法返回的其实是一个LoaderManagerImpl的实例,所以我们要同时研究LoaderManager和LoaderManagerImpl 。

Loader及其相关类的源码地址如下: Loader源码 AsyncTaskLoader源码 CursorLoader源码

started

Loader在执行了startLoading()方法后,会进入started状态,LoaderManager会在合适的时机执行Loader.startLoading()方法,概括来说,当我们执行LoadManager.initLoader()时,如果Loader不存在,内部会执行LoadCallbacks的onCreateLoader()方法创建Loader,并让新创建的Loader执行startLoading()方法。

具体执行过程如下: LoaderManager.initLoader() -> LoaderManager.createAndInstallLoader() -> LoaderManager.createLoader() -> LoaderCallbacks.onCreateLoader() -> 得到loader之后创建LoaderInfo -> LoaderManager.installLoader() -> 将其放入LoaderManager内部维护的mLoaders数组中 -> LoaderInfo.start() -> Loader处于started状态 -> Loader.startLoading() ->

我们可以在onStartLoading()中写我们的逻辑,在started状态下,Loader应该监控数据源的变化,并将新数据发送给客户端,具体来说就是当监控到新数据后,调用Loader.deliverResult()方法,触发LoadCallbacks.onLoadFinished()回调的执行,从而客户端可以从该回调中轻松获取数据。

CursorLoader重写了Loader中的onStartLoading()方法,以下是CursorLoader在执行到onStartLoading()之后的逻辑,从中我们可以看出AsyncLoader和CursorLoader如何实现异步加载数据。

CursorLoader.onStartLoading() -> AsyncTaskLoader.forceLoad() -> Loader.forceLoad() -> AsyncTaskLoader.onForceLoad() -> AsyncTaskLoader.executePendingTask() -> 进入异步线程-> LoadTask.doInBackground() -> AsyncTaskLoader.onLoadInBackground() -> AsyncTaskLoader.doInBackground() -> 得到实际的数据 -> 退出异步线程,返回主线程 -> LoadTask.onPostExecute() -> AsyncTaskLoader.dispatchOnLoadComplete() -> CursorLoader.deliverResult() -> Loader.deliverResult() -> LoaderInfo.onLoadComplete() -> LoaderInfo.callOnLoadFinished() -> LoaderCallbacks.onLoadFinished()

stopped

Loader在执行了stopLoading()状态后,会进入stopped状态,LoaderManager会在合适的时机执行Loader.stopLoading()方法,概括来说,当Activity将要处于stopped状态的时候会执行Activity的performStop()方法,在该方法内会执行FragmentController的doLoaderStop()方法,在该方法内又会执行FragmentHostCallback的doLoaderStop()方法,在该方法内部会执行LoaderManager的doStop()方法,在该方法内,,LoaderManager会遍历所有的内部存储的LoaderInfo,依次执行LoaderInfo的stop()方法,在该方法中内部又会调用Loader.stopLoading()方法,此时Loader进入stopped方法,然后执行Loader的stopLoading()。

拥有一颗比九万五千公里还辽阔的心,

深入源码解析Android中Loader、AsyncTaskLoader、CursorLoader、

相关文章:

你感兴趣的文章:

标签云: