【问题标题】:Android Loader not triggering callbacks on screen rotateAndroid Loader 不会在屏幕旋转时触发回调
【发布时间】:2012-09-12 12:34:15
【问题描述】:

我正在使用AsyncTaskLoader。我有一个实现LoaderCallbacks(支持库)的活动。

我已调试断点并将其放入日志,加载程序会传递结果,但是第二次回调onLoadFinished 未触发。奇怪的是 - 当我再次旋转时它起作用了,当我回到它时,我开始的任何方向都会得到回调。

在我的活动onResume

LoaderManager lm = getSupportLoaderManager();
Loader loader = lm.initLoader(0, null, new LoaderManager.LoaderCallbacks<String>() {

        @Override
        public Loader<String> onCreateLoader(int i, Bundle bundle) {
            Loader<String> loader = new TestLoader(MainActivity.this);
            return loader;
        }

        @Override
        public void onLoadFinished(Loader<String> stringLoader, String s) {
            Log.d(Application.TAG, "OnLoadFinished " + s);
            doStuff(s);
        }

        @Override
        public void onLoaderReset(Loader<String> stringLoader) {
            // NOP
        }
    });

在我的加载器中:

public class TestLoader extends AsyncTaskLoader<String> {
    private String mData;

    public TestLoader(Context context) {
        super(context);
    }

    // This get's called after a loader is initialized or a loader 
    // that is alive still is reset
    @Override
    public void onStartLoading() {
        if (mData != null) { // Have our data loaded, just deliver it!
            deliverResult(mData);
        }
        if (takeContentChanged() || mData == null) {
            forceLoad();
        }
    }

    // This is called when an Activity or Fragment requests a loader 
    // to be reset because they want new data
    @Override
    public void onReset() {
        mData = null;
        // Ensure that the old task is cancelled if it was running
        // We do NOT have to call forceLoad here because onStartLoading 
        // will get called after this
        cancelLoad();
    }

    // Here we just want to store our own data we got and reset our boolean
    @Override
    public void deliverResult(String data) {
        Log.d(Application.TAG, "deliverResult " + data);
        mData = data;
        super.deliverResult(mData);
    }

    @Override
    public String loadInBackground() {
       // returns content from a content provider ... 
    }
}

真的被这个迷惑了,我是 Android 新手,所以也许这对其他人来说是显而易见的 :)

【问题讨论】:

  • 我也一直在努力解决这个问题,但我也是 Android 新手。我能有所作为的唯一方法是确保在 Activity 的 onCreate() 中调用 get(Support)LoaderManager(),然后即使在其他地方调用 initLoader() 也能正常工作。在 Activity 类中调试内部加载器变量的序列和生命周期非常困难,希望有人了解发生了什么。
  • 我同样遇到了这个问题 - 我在导航监听器中调用 getSupportLOaderManager().restart .. 直接在 onCreate 中实例化它并在监听器中访问它使它工作但我不知道为什么..有人吗?
  • onResume 通常是做这些事情的错误地方。我的答案中有更多详细信息。

标签: android android-loadermanager android-loader


【解决方案1】:

如果是Activity,您至少必须简单地在onCreate() 中调用getSupportLoaderManager() / getLoaderManager(),如果是Fragment,则必须调用onActivityCreated()。实际的initLoader() 可以在其他地方。否则加载器将处于停止状态,即使完成加载也不会传递结果。我怀疑这是因为加载器管理器不会将旧加载器重新附加到新的Activity,除非在新的ActivityonCreate() 中进行上述调用。

【讨论】:

  • 解决了我的奇怪问题,只发生在单个片段上,其他片段工作正常
【解决方案2】:

你有

Loader loader = lm.initLoader(...)

你应该有

Loader loader = new LoaderManager.LoaderCallbacks(...) {...}

在你的onResume()

this.getLoaderManager().restartLoader(0, null, this.loader);

Loaders documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多