我正在尝试理解AsyncTaskLoaders的一些细节。这可能对其他人来说很明显,但我找不到一个清晰的示例或定义来演示和解释当您覆盖deliverResult()
方法时会发生什么。实际上传递了什么?这如何与调用对象交互?我可以看到使用super.deliverResult
,它从类中传递一个私有对象。那么,加载器自动知道要与“传递的结果”关联什么吗?我完全困惑了。
我正在尝试理解AsyncTaskLoaders的一些细节。这可能对其他人来说很明显,但我找不到一个清晰的示例或定义来演示和解释当您覆盖deliverResult()
方法时会发生什么。实际上传递了什么?这如何与调用对象交互?我可以看到使用super.deliverResult
,它从类中传递一个私有对象。那么,加载器自动知道要与“传递的结果”关联什么吗?我完全困惑了。
看起来我有点晚了,但无论如何...
这个中介步骤在后台加载和UI线程的回调onLoadFinished()
被调用之间的一个主要优点之一是
loadInBackground()
deliverResult()
和onLoadFinished()
它为我们提供了一种从AsyncTaskLoader
类内部快捷跳过整个加载过程的方法。
如果有缓存数据,这可以很好地用于在您的AsyncTaskLoader中缓存加载结果并阻止后台加载。
为什么我们要这样做呢?难道不是加载器处理那些可怕的活动生命周期问题(例如旋转设备)、维护状态(如缓存数据)并有一种在底层数据更改时获得更新的方法(CursorLoader)的全部内容吗?
好吧,是的,但这并不是全部故事。
这里有一个链接,指向一个实现了此行为的样例应用程序(sample app which implements this behaviour)。 这只是一款“玩具应用程序”,因此是Udacity当前版本“Developing Android Apps”基础课程的一部分。而这个链接则指向该课程中处理此问题的相应视频。(该课程是免费的,但您仍需要在Udacity上注册)。
简而言之,这个应用程序展示了一个UI,用户可以在其中输入搜索查询以搜索GitHub的repos(通过GitHub API),将结果搜索URL显示在TextView中,并在另一个TextView中显示从GitHub获取的原始JSON。MainActivity.java
中,这里的相关部分位于实现为匿名内部类的AsyncTaskLoader
中:
For step 1, just introduce a member variable in your AsyncTaskLoader
implementation that's meant to serve as your data cache.
/* This String will contain the raw JSON
from the results of our Github search */
String mGithubJson;
For step 2, override deliverResult()
as to cache the loading result.
When loadInBackground()
has finished, it passes its return value to deliverResult()
.
It does so anyway, but now that we've overridden deliverResult() we can step right in and store our fetched data into the cache member variable which we've created with just so good foresight.
And finally, we chain up to the super class implementation of deliverResult() with super.deliverResult()
which will pass-on the result to the callback method onLoadFinished()
, running on the UI thread.
@Override
public void deliverResult(String githubJson) {
mGithubJson = githubJson;
super.deliverResult(githubJson);
}
For step 3, check in onStartLoading()
whether or not we've got cached data.
If we don't have cached data (yet), just force the loading to begin with a call to forceLoad()
.
But if we do have cached data, just call deliverResult(yourCachedDataGoesHere)
and pass-in the cached data as argument.
if (mGithubJson != null) {
deliverResult(mGithubJson);
} else {
forceLoad();
}
So, if you now switch back and forth between your app and some other app(s), you'll notice that no reloading takes place, as the loader will just use your cached data.
deliverResult()
之后onLoadFinished()
没有被调用。你有什么想法吗? - imran.razakAsyncTaskLoader
将调用deliverResult()
方法,将数据传递给onLoadFinished()
方法进行显示。loadInBackground()
之前会调用onStartLoading()
。在此方法中,我们可以检查数据是否为空,如果不为空,则调用deliverResult()
并将结果发送到onLoaderFinished()
,这样可以防止重新加载数据。我能找到的唯一有意义的答案是基于this链接中的描述。
“注册侦听器以在加载完成时接收Loader的结果。对于每个Loader,LoaderManager都会注册一个OnLoadCompleteListener,它将通过调用onLoadFinished(Loader loader,D result)将Loader的交付结果转发给客户端。Loader应使用Loader#deliverResult(D result)调用将结果传递给这些已注册的侦听器。”
当您有AsyncTask的侦听器并希望将结果发送回它们时,似乎可以使用deliverResult。我会说这很不常见。 {{link2:Android文档}}甚至更少描述:
“将加载的结果发送到已注册的侦听器。只应由子类调用。必须从进程的主线程调用。
参数
data:加载的结果”
deliverResult 在 doInbackground 完成后起作用。它将结果 D(由 doInBackground 返回)发送到调用线程。您可能希望重写它以清理数据,但是您可以在 doInBackground 中进行清理而无需重写 deliverResult。