【问题标题】:Android LoaderCallbacks.onLoadFinished with Fragment transaction: Is this right?Android LoaderCallbacks.onLoadFinished with Fragment transaction:对吗?
【发布时间】:2015-05-16 01:47:53
【问题描述】:

谁能告诉我我是否理解正确?我所拥有的似乎有效,但它似乎比许多加载器示例更复杂......我想知道我是否有过于复杂的事情。我有一个使用多个 AsyncTaskLoader 的活动。因此,我为 LoaderCallbacks 实现内部类,而不是让活动实现 LoaderCallback 接口。我读到匿名内部类可以泄漏活动,所以我不得不将它创建为一个对活动的弱引用的静态类。 onLoadFinished 需要执行一个片段事务,所以我需要一个处理程序。再次是内部类活动泄漏问题,因此 Handler 是一个静态类。此外,我读到可以在 Activity 暂停时调用 handleMessage,因此我需要在 Handler 中实现 pause 和 resume 方法。这真的都是必要的吗?

 //here are the relavent bits from my activity
private static class SessionListener implements LoaderManager.LoaderCallbacks<SessionStatus> {
    private final WeakReference<MainActivity> mTarget;

    private SessionListener(MainActivity target) {
        this.mTarget = new WeakReference<>(target);
    }

    @Override
    public Loader<SessionStatus> onCreateLoader(int id, Bundle args) {
        return  new SessionCheckLoader(mTarget.get(), args);
    }

    @Override
    public void onLoadFinished(Loader<SessionStatus> arg0, SessionStatus arg1) {
        MainActivity target = mTarget.get();

        if (arg1 == MainActivity.SessionStatus.CLOSED && target != null) {
            target.mHandler.sendEmptyMessage(MSG_SHOW_CLOSED_DIALOG);
        }
    }

    @Override
    public void onLoaderReset(Loader<SessionStatus> arg0) {


    }
};

//the handler with pause/resume
 private static class HandlerClass extends Handler {
    private final WeakReference<MainActivity> mTarget;

    public HandlerClass(MainActivity context) {
        mTarget = new WeakReference<>(context);
    }
    Stack<Message> s = new Stack<>();
    boolean is_paused = false;

    public synchronized void pause() {
        is_paused = true;
    }

    public synchronized void resume()  {
        is_paused = false;
        while (! s.empty())
        {
            sendMessageAtFrontOfQueue(s.pop());
        }
    }
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (is_paused) {
            s.push(Message.obtain(msg));
            return;
        }
        MainActivity target = mTarget.get();
        if (target != null) {
            if (msg.what == MSG_SHOW_CLOSED_DIALOG) {
                target.sessionDialog();
            }else if (msg.what == MSG_POP_STACK) {
                target.getSupportFragmentManager().popBackStack(null, 0);
            }
        }
    }
}

 private LoaderManager.LoaderCallbacks<SessionStatus> sessionCheckListener = new SessionListener(this);
private HandlerClass mHandler = new HandlerClass(this);

@Override
protected void onPause() {
    super.onPause();
    mHandler.pause();
}

@Override
protected void onPostResume() {
    super.onPostResume();
    mHandler.resume();
}

【问题讨论】:

    标签: android android-fragments loader android-handler


    【解决方案1】:

    您仍然可以在Activity 中实现回调。当调用initLoader() 时,为每个Loader 提供一个唯一的ID。在每个回调的switch 语句中使用Loader.getId() 来确定它是哪个Loader

    【讨论】:

    • 我已经按照您所说的方式查找了一个示例,其中加载程序具有不同的返回类型。我发现 ppl 说要实现不同的类。不过,我仍然希望看到这样的例子。
    • 尝试使Activity 实现LoaderCallbacks&lt;Object&gt;,然后将其转换为switch-case 中适当的加载器类型。
    • 我会试试看的。那么 Handler 部分是否正确?真的需要暂停/恢复吗?我想我很困惑,因为我理解它的方式需要处理程序,因为您无法从 onLoadFinished 方法提交片段事务,但看起来处理程序也可能在错误的时间被调用以提交片段事务?
    • onLoadFinished 保证在开始/停止之间被调用,所以我认为你可以使用事务。您不必担心暂停/恢复。在可能的情况下,将加载程序放在相关片段而不是活动中,并使用主机活动接口模式在片段和主机活动之间进行通信。这将有助于将每个活动/片段限制为一个加载器,并大大简化代码。
    • 但它在 onLoadFinished 的 javadoc 中说:请注意,通常不允许应用程序在此调用中提交片段事务,因为它可能在保存活动状态后发生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2021-11-29
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多