【问题标题】:How to get the result of a loader if the screen was rotated during its job?如果屏幕在工作期间旋转,如何获得加载程序的结果?
【发布时间】:2016-09-08 00:10:39
【问题描述】:

我听说加载器可以帮助在方向更改期间保存异步作业的结果。我有一个片段执行带有一些参数的加载器。我应该怎么做才能重新连接到装载机?重要提示:如果 LoaderCallbacks.onLoadFinished() 已处理结果,我不想重新启动加载程序。
更详细:我有一个带有文本字段的片段。当用户输入一些文本并按 Enter 时,我应该使用网络请求开始搜索。我通过启动装载机来做到这一点

 private void loadFirstPage() {
    LoaderManager loaderManager = getLoaderManager();
    data.currentPage = 1;

    Bundle args = new Bundle();
    args.putString(VacanciesAsyncLoader.ARG_SEARCH_TEXT, data.query);
    args.putInt(VacanciesAsyncLoader.ARG_ITEMS_PER_PAGE, Const.ITEM_PER_PAGE);
    args.putInt(VacanciesAsyncLoader.ARG_PAGE_NUMBER, data.currentPage);
    loaderManager.restartLoader(GET_VACANCIES_LOADER_ID, args, this);
}

@Override
public void onViewCreated(Bundle savedInstanceState) {
    super.onViewCreated(savedInstanceState);
    if (savedInstanceState == null) {
        // ...
    } else {
        data = savedInstanceState.getParcelable(KEY_DATA);
        restoreViewState(data);
        reconnectLoaderIfNeeded();
    }
}

private void reconnectLoaderIfNeeded() {
    EnumSet<State> loadingStates =
            EnumSet.of(State.REFRESHING, State.LOADING_FIRST_PAGE, State.LOADING_ADDITIONAL_PAGE);
    if (loadingStates.contains(data.state)) {
        getLoaderManager().initLoader(GET_VACANCIES_LOADER_ID, null, this);
    }
}

我想在屏幕旋转时重新连接到它。如果我处理了它的结果,我不想再次触发它。

【问题讨论】:

  • 加载程序自动重新连接。您可以根据需要多次调用 initLoader,但加载程序不会重置。你想在 onloadFinished() 中更新什么?
  • @masp 我担心 initLoader 会重新启动作业,即使它已完成并已处理。现在,我决定保存我是否仍在加载某些内容的状态,如果是,那么我调用 initLoader 时不带参数。似乎正在工作,但我不确定使用参数启动加载程序是否正确,并且在屏幕旋转后,我调用 initLoader 而不传递参数
  • 检查这个androiddesignpatterns.com/2012/08/implementing-loaders.html 如果你能发布一些代码会更好,因为这听起来不像是正确的加载器功能。
  • @masp 我已经更新了帖子。实际上,我还在同一屏幕上使用加载器来加载其他项目并刷新项目。现在,我保持加载状态并为适当的加载器调用 initLoader() ,当加载器完成时,我取消设置加载状态。它似乎工作。但是我不确定用一些 args 启动加载器并通过将 null 作为 args 重新连接到它是否是一个好习惯
  • 我看不到你的所有代码,所以我不知道它是如何工作的,但是 restartLoader 与 initLoader 不同。

标签: android loader screen-rotation


【解决方案1】:

如果这只是一次性请求,那么典型的模式应该是:

发起请求:

getLoaderManager().restartLoader(LOADER_ID, args, callbacks);

onCreate(),检查Loader是否还在运行:

if (savedInstanceState != null) {
    // If it exists, init with null arguments (since they won't
    // be used) to reconnect the callbacks
    if (getLoaderManager().getLoader(LOADER_ID) != null) {
        getLoaderManager().initLoader(LOADER_ID, null, callbacks);
    }
}

在你的onLoadFinished(),销毁加载器:

getLoaderManager().destroyLoader(LOADER_ID);

假设您已正确实施您的Loader,这应该可以解决问题。

【讨论】:

  • 谢谢。这是一个很好的模式,允许不存储额外的标志!
【解决方案2】:

您在 Activity 中设置此代码(用于片段)。

AndroidManifest.xml:

android:configChanges="orientation|keyboardHidden"
...
<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="orientation|keyboardHidden"
        >

【讨论】:

  • 以这种方式处理方向变化并不是一个好习惯。
  • 我觉得你最好用"initLoader"
【解决方案3】:

这篇文章在处理有关异步任务的方向变化方面帮助了我很多。它与保留片段有关:

http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

希望对你有帮助

【讨论】:

  • 是的,这是一件很酷的事情。可悲的是,我只能使用装载机,因为我正在为一份新工作实施一项测试任务,而雇主想看看我是如何管理它的
猜你喜欢
  • 2020-04-07
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多