1

在下面的 onloadfinished 方法中,我试图在结果为空时打开一个对话框片段。但是它给了我错误,而打开警报对话框可以正常工作。

java.lang.IllegalStateException: Can't perform this action inside of onLoadFinished

这个错误在这里说明了什么:

@Override
public void onLoadFinished(Loader<Map<String, Integer>> arg0,
        Map<String, Integer> result) {
    if (result == null) {
        /*netEMessage();
         * At this place i was calling alert dialog before but Now calling Dialog in onload finished gives me error*/
        return;
    }
}



private void netEMessage() {

    NetowrkErrorDialog mErrorDialog = NetowrkErrorDialog.newInstance();
    mErrorDialog.setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_DeviceDefault_NoActionBar_Fullscreen);
    mErrorDialog.setCancelable(false);
    mErrorDialog.show(mOrderActivity.getSupportFragmentManager(), "networkerror");
}

完成 logcat 错误

    0java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished
1at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1331)
2at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
3at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
4at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
5at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
6at com.fss.pos.presentation.MenuFragment.netEMessage(MenuFragment.java:178)
7at com.fss.pos.presentation.MenuFragment.onLoadFinished(MenuFragment.java:144)
8at com.fss.pos.presentation.MenuFragment.onLoadFinished(MenuFragment.java:1)
9at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427)
10at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395)
11at android.support.v4.content.Loader.deliverResult(Loader.java:103)
12at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:221)
13at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
14at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
15at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
16at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
17at android.os.Handler.dispatchMessage(Handler.java:99)
18at android.os.Looper.loop(Looper.java:137)
19at android.app.ActivityThread.main(ActivityThread.java:5041)
20at java.lang.reflect.Method.invokeNative(Native Method)
21at java.lang.reflect.Method.invoke(Method.java:511)
22at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
23at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
24at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

6

这里有一些背景可以帮助遇到此异常的任何人。

抛出异常是因为框架不允许在与 onLoadFinished() 相同的调用堆栈中提交片段事务。这种行为提供了防止状态丢失的保护,因为加载程序通常基于后台线程(AsyncTaskLoader),可以完成他们的工作并随时通知回来。

可能存在两个潜在问题: 1. 执行 onLoadFinished() 调用时,框架已经在片段管理器中保存了片段的状态(例如由于方向变化)。在此上下文中提交事务将导致状态丢失,因为此延迟事务不包含在已保存状态中。2. 框架尚未完成从先前保存状态的恢复。在这里,交易在状态恢复之前来得太早。

上面 Maria 的回答有两个问题: 1. 调用 runOnUiThread() 没有帮助,因为在 UI 线程上调用 onLoadFinished() 这意味着对 runOnUiThread() 的调用将在同一个调用堆栈中调用,这将引发异常. 文档说:“如果当前线程是 UI 线程,则立即执行该操作。” 2. 即使调用(此处为 DialogFragment.show())未在同一个调用堆栈中完成),例如:

public void onLoadFinished(Loader<Map<String, Integer>> arg0,
                            Map<String, Integer> result) {
    if (result == null) {

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                netEMessage();
            }
        });
    } 
}

上述风险依然存在。

此问题的最佳解决方案是将片段事务移动到流程中的不同位置,同时确保上述问题 1. 和 2. 不会​​发生。例如,从 Activity.onPostResume() 执行事务。

祝你好运!

于 2015-03-16T07:40:10.157 回答
0

问题是因为您无法更改、显示或做与您的视图或视觉组件有关的事情。如果你想做这样的事情,你需要用户下一个代码:

An_Activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        //Here call your method 
        netEMessage();
    }
});

An_Activity 是任何活动(在这种情况下,您调用线程的活动或类似的活动。

在您的特定情况下,将代码放在 if 中:

if (result == null) {
    /*netEMessage();
     * At this place i was calling alert dialog before but Now calling Dialog in onload finished     gives me error*/

    (Put the Code here)

    return;
}
于 2013-06-25T20:58:39.180 回答