我试图了解AsyncTaskLoaders的一些要点。这对于其他人可能是显而易见的,但是我找不到一个明确的示例或定义来演示和示范当您覆盖deliverResult()方法时发生的情况。实际交付了什么?这如何与调用对象交互?我可以看到super.deliverResult的使用,它传递了类中的私有(private)对象。因此,加载程序是否自动知道与“交付结果”相关联的内容。我很困惑。

最佳答案

看来我参加聚会有点晚了,但是无论如何...

在后台加载和UI线程的回调onLoadFinished()被调用之间进行此中间步骤的主要优势之一

  • loadInBackground()
  • deliverResult()
  • 回调onLoadFinished()

  • 是它为我们提供了一种快捷方式,从AsyncTaskLoader类内部缩短了整个加载过程的方法。
    这可以很好地用于在AsyncTaskLoader和中缓存加载结果,从而防止在存在缓存数据的情况下进行后台加载。

    为什么我们要这样做呢?加载程序的全部目的不是处理那些令人恐惧的 Activity 生命周期问题(例如旋转设备),维护状态(例如缓存数据)并具有在基础数据发生更改时进行更新的方法(CursorLoader)吗?
    好吧,是的,但这不是全部。

    考虑以下用例:
    您已启动并运行您的应用程序(带有AsynTaskLoader的应用程序),并且该应用程序已将数据加载到您的UI中。
    然后,您切换到Twitter应用程序以查看一些新闻并返回到您的应用程序。
    无需缓存,返回到您的应用程序后,加载程序将执行重新加载的操作。
    此行为与配置更改后的行为不同,例如旋转设备,在这种情况下将不会重新加载。

    因此,如果我们只是将应用程序发送到后台,然后又返回到后台,那么如何防止加载程序重新获取数据呢?

    解决方案
  • AsyncTaskLoader实现中创建一个缓存成员变量。
  • 覆盖 deliverResult(),以便在调用父类的deliveryResult()实现之前,先将获取的数据保存在缓存中。
  • onStartLoading() 中,检查是否存在缓存的数据,如果存在,请让您的AsyncTaskLoader交付它。否则,请开始加载。

  • 这是sample app which implements this behaviour的链接。
    它只是一个“玩具应用程序”,也是Udacity当前版本"Developing Android Apps" fundamentals course的一部分。并把here is the link放到处理该问题的类(class)中的相应视频上。 (该类(class)是免费的,但您仍然必须使用Udacity进行注册)。

    简而言之,此应用程序演示的是一个用户界面,用户可以在其中输入搜索查询(通过GitHub API)以搜索GitHub的仓库,在TextView中显示最终的搜索URL,并在另一个TextView中显示从GitHub获取的原始JSON。 。
    整个操作仅发生在MainActivity.java中,这里的相关部分在AsyncTaskLoader中,该AsyncTaskLoader是作为匿名内部类实现的:
  • 对于步骤1,只需在deliverResult()实现中引入成员变量即可用作数据缓存
    /* This String will contain the raw JSON
       from the results of our Github search */
    String mGithubJson;
    
  • 对于步骤2,覆盖 loadInBackground()以缓存加载结果。deliverResult()完成后,它将其返回值传递给super.deliverResult()
    无论如何,它都是这样做的,但是现在我们已经覆盖了deliveryResult(),我们可以直接进入并将将获取的数据存储到中,并将我们获取的数据存储到我们以非常好的预见性创建的缓存成员变量中。
    最后,我们使用onLoadFinished()链接到liverResult()的父类(super class)实现,它将结果传递给在UI线程上运行的回调方法onStartLoading()
    @Override
    public void deliverResult(String githubJson) {
        mGithubJson = githubJson;
        super.deliverResult(githubJson);
    }
    
  • 对于步骤3,检查forceLoad()中的是否我们是否已缓存数据
    如果还没有缓存数据,只需强制加载从对deliverResult(yourCachedDataGoesHere)的调用开始即可。
    但是,如果确实有缓存的数据,则只需调用ojit_code并将传入的数据作为参数传入即可。
    if (mGithubJson != null) {
        deliverResult(mGithubJson);
    } else {
        forceLoad();
    }
    

    因此,如果您现在在您的应用程序和其他一些应用程序之间来回切换,您会注意到没有重新加载发生,因为加载器只会使用您缓存的数据。
  • 10-08 03:30