在onloadfinished中打开对话框片段时出现java.lang.IllegalStateException

时间:2013-06-25 10:34:13

标签: android

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

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)

2 个答案:

答案 0 :(得分:6)

以下是帮助遇到此异常的任何人的背景知识。

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

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

玛丽亚的回答有两个问题: 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()执行事务。

祝你好运!

答案 1 :(得分: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;
}