简体   繁体   English

IllegalStateException:无法在onSaveInstanceState - Android之后执行此操作

[英]IllegalStateException: Can not perform this action after onSaveInstanceState - Android

I am trying to figure out why my android app crashes sometimes, with the above exception. 我试图弄清楚为什么我的Android应用程序有时崩溃,上面的例外。 I can't find the source of the problem from what the logcat says. 我无法从logcat所说的内容中找到问题的根源。

It happens rarely. 它很少发生。

Logcat output: Logcat输出:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360) at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378) at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:282) at android.view.View.dispatchAttachedToWindow(View.java:12752) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2577) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1427) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192) at and java.lang.IllegalStateException:在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360)在android.support.v4.app.FragmentManagerImpl.enqueueAction(之后的onSaveInstanceState无法执行此操作FragmentManager.java:1378 )在android.support.v4.app.BackStat.et.FotmentTabHost的android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)。 onAttachedToWindow(FragmentTabHost.java:282)在android.view.View.dispatchAttachedToWindow(View.java:12752)在android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2577)在android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java :2584)在android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584)在android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2584)在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1427)在机器人.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192)at和 roid.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6231) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788) at android.view.Choreographer.doCallbacks(Choreographer.java:591) at android.view.Choreographer.doFrame(Choreographer.java:560) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) at dalvik.system.NativeStart.main(Native Method) roid.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:6231)at android.view.Choreographer $ CallbackRecord.run(Choreographer.java:788)at android.view.Choreographer.doCallbacks(Choreographer.java:591)at android .view.Choreographer.doFrame(Choreographer.java:560)位于android.view上的android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:774)android.os.Handler.handleCallback(Handler.java:808)。在android.app.Looper.loop(Looper.java:193)上的Handler.dispatchMessage(Handler.java:103)位于android.app.ActivityThread.main(ActivityThread.java:5292)的java.lang.reflect.Method.invokeNative (本地方法)位于com.android.internal.os的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:824)的java.lang.reflect.Method.invoke(Method.java:515) .zygoteInit.main(ZygoteInit.java:640)at dalvik.system.NativeStart.main(Native Method)

Main Activity: 主要活动:

public class MainActivity extends FragmentActivity {

    private FragmentTabHost mTabHost;    
    private UiLifecycleHelper uiHelper;

    LocationClient mClient;
    LocationRequest mRequest;
    private String user;
    private String userId;
    private ImageButton addPlaceBtn;
    private SQLiteDataSource datasource;
    private TextView notifTextView;
    private boolean appIsOn = false; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayShowTitleEnabled(false);
        setContentView(R.layout.activity_main);

        datasource = new SQLiteDataSource(this);
        datasource.open();

        uiHelper = new UiLifecycleHelper(this, null);
        uiHelper.onCreate(savedInstanceState);

        if (isFacebookLoggedIn()) {
            System.out.println("We are logged in!");
        } else {
            showLogin();
        }

        if (datasource.getAllImageItems().isEmpty()) {
            Intent splash = new Intent(this, SplashActivity.class);
            startActivity(splash);
        }

        addPlaceBtn = (ImageButton) findViewById(R.id.addPlace1);

        uiHelper = new UiLifecycleHelper(this, null);
        uiHelper.onCreate(savedInstanceState);

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(),
                android.R.id.tabcontent);

        mTabHost.addTab(
                mTabHost.newTabSpec("tab1").setIndicator("PREPARATE", null),
                OffersFragmentActivity.class, null);
        mTabHost.addTab(
                mTabHost.newTabSpec("tab2").setIndicator("CATEGORII", null),
                CategoriesActivity.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab3")
                .setIndicator("CAIETE", null), BooksFragmentActivity.class,
                null);

        for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); i++) {
            mTabHost.getTabWidget().getChildAt(i)
                    .setBackgroundResource(R.drawable.tab_text_selector);
            mTabHost.getTabWidget().setDividerDrawable(R.drawable.divider);
            final TextView tv = (TextView) mTabHost.getTabWidget()
                    .getChildAt(i).findViewById(android.R.id.title);
            if (tv == null)
                continue;
            else
                tv.setTextColor(0xFFFFFFFF);
        }

        mTabHost.setOnTabChangedListener(new OnTabChangeListener() {

            public void onTabChanged(String tabId) {

                switch (mTabHost.getCurrentTab()) {
                case 0:
                    addPlaceBtn.setVisibility(View.VISIBLE);
                    break;
                case 1:
                    addPlaceBtn.setVisibility(View.GONE);
                    break;
                case 2:
                    addPlaceBtn.setVisibility(View.GONE);
                    break;

                default:

                    break;
                }
            }
        });

        addPlaceBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (user != null && isOnline()) {
                    Intent i = new Intent(getApplication(),
                            CameraActivity.class);
                    startActivity(i);
                } else if (user == null) {
                    // If user is not logged in, start login activity
                    Intent i = new Intent(getApplication(), LoginActivity.class);
                    startActivity(i);
                } else if (!isOnline()) {
                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                            MainActivity.this);
                    alertDialogBuilder.setTitle("Internetul este oprit");
                    alertDialogBuilder
                            .setMessage("Pentru actualizarea continutului aveti nevoie de internet. Porniti acum?");
                    alertDialogBuilder.setPositiveButton("Da",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // go to a new activity of the app
                                    Intent settingsIntent = new Intent(
                                            Settings.ACTION_DATA_ROAMING_SETTINGS);
                                    settingsIntent
                                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(settingsIntent);
                                    finish();
                                }
                            });
                    // set negative button: No message
                    alertDialogBuilder.setNegativeButton("Nu",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    // cancel the alert box and put a Toast to
                                    // the user
                                    finish();
                                }
                            });

                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();
                }
            }
        });

        if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
            Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);        
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));

        final Menu m = menu;
        final MenuItem item = menu.findItem(R.id.action_notifications);
        View actionView = item.getActionView();
        notifTextView = (TextView) actionView.findViewById(R.id.notifTextView);

        String unreadNotifs = datasource.countUnreadNotif();
        if (!unreadNotifs.equals("0")) {
            notifTextView.setText(unreadNotifs);
        } else {
            notifTextView.setVisibility(View.GONE);
        }

        item.getActionView().setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                m.performIdentifierAction(item.getItemId(), 0);

            }
        });

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_user) {
            Intent i = new Intent(this, UserProfile.class);
            i.putExtra("user", user);
            i.putExtra("userId", userId);
            startActivity(i);

            return true;
        }

        if (id == R.id.action_notifications) {
            Intent i = new Intent(this, Notifications.class);
            startActivity(i);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private boolean isFacebookLoggedIn() {
        Session session = Session.getActiveSession();

        if (session != null) {
            // Session can be open, check for valid token
            if (!session.isClosed()) {
                if (!session.getAccessToken().equalsIgnoreCase("")) {
                    return true;
                }
            }
        }
        return false;
    }

    // FB Login Session and user info
    public void showLogin() {
        Intent i = new Intent(this, LoginActivity.class);
        startActivity(i);

    }

    @Override
    protected void onResume() {
        super.onResume();
        uiHelper.onResume();
        appIsOn = true;
        invalidateOptionsMenu();

        if (!isOnline()) {
            showGpsButton();
        }

        SharedPreferences preferences = getSharedPreferences("USERINFO",
                Context.MODE_PRIVATE);
        user = preferences.getString("name", null);
        userId = preferences.getString("userId", null);
        userId = preferences.getString("userId", null);

        GCMActivity gcm = new GCMActivity(this);
        gcm.registerIfNeeded();

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
        appIsOn = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
        datasource.deleteAllRows();

    }

    public void showGpsButton() {
        LinearLayout buttonLayout = (LinearLayout) findViewById(R.id.gpsWarning);
        buttonLayout.setVisibility(View.VISIBLE);
        buttonLayout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent settingsIntent = new Intent(
                        Settings.ACTION_DATA_ROAMING_SETTINGS);
                settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(settingsIntent);
                finish();
            }
        });
    }

    public boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected()) {
            return true;
        }
        return false;
    }
}

I was experiencing a similar issue on KitKat. 我在KitKat上遇到了类似的问题。 But on Lollipop it seems to work fine. 但是在Lollipop上似乎工作得很好。 Regardless, we have to support many OS versions, right? 无论如何,我们必须支持许多操作系统版本,对吧? :) :)

The primary cause seems to be that the starting of a new activity is forcing the MainActivity to pause before it's even completely finished creating. 主要原因似乎是新活动的开始迫使MainActivity在完成创建之前暂停。 When it pauses, it saves the instance state right away. 当它暂停时,它会立即保存实例状态。 But since Fragment instances get committed in a weird end-of-main-thread cycle, that start-pause-save cycle becomes out of order throwing this crash. 但是,由于Fragment实例在一个奇怪的主线程循环周期中被提交,因此该开始 - 暂停 - 保存周期变得无序,从而导致崩溃。 And in some cases, it could be a race condition and happen sporadically. 在某些情况下,它可能是一种竞争条件,偶尔也会发生。

Here's some code that seems to fix it after repeated testing: 以下是一些似乎在重复测试后修复它的代码:

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);

    Handler hanlder = new Handler();
    hanlder.post(new Runnable() {
        @Override
        public void run() {
            if (isFacebookLoggedIn()) {
                System.out.println("We are logged in!");
            } else {
                showLogin();
            }

            if (datasource.getAllImageItems().isEmpty()) {
                Intent splash = new Intent(MainActivity.this, SplashActivity.class);
                startActivity(splash);
            }
        }
    });
}

The trick is to spawn a Handler and post to the end of the main thread to guarantee it will happen after all Fragment instances have been committed. 诀窍是生成一个Handler并发布到主线程的末尾,以保证在所有Fragment实例提交后它将发生。 Doing it in onPostCreate instead of immediately in onCreate should help the situation as well. onPostCreate而不是在onCreate中立即执行它也应该有助于这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android ShowDialog:IllegalStateException:在onSaveInstanceState之后无法执行此操作 - Android ShowDialog : IllegalStateException: Can not perform this action after onSaveInstanceState Android java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作 - Android java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState Android:如何单元测试“IllegalStateException:onSaveInstanceState后无法执行此操作” - Android: How to unit test “IllegalStateException: Can not perform this action after onSaveInstanceState” Android ViewPager IllegalStateException:onSaveInstanceState之后无法执行此操作 - Android ViewPager IllegalStateException: Can not perform this action after onSaveInstanceState IllegalStateException:在使用 ViewPager onSaveInstanceState 后无法执行此操作 - IllegalStateException: Can not perform this action after onSaveInstanceState with ViewPager 在onsaveinstancestate之后,IllegalStateException无法执行此操作 - IllegalStateException can not perform this action after onsaveinstancestate IllegalStateException: 在 onSaveInstanceState 和 onActivityResult 之后无法执行此操作 - IllegalStateException: Can not perform this action after onSaveInstanceState with onActivityResult 避免IllegalStateException“ onSaveInstanceState之后无法执行此操作” - Avoiding IllegalStateException “Can not perform this action after onSaveInstanceState" IllegalStateException:onSaveInstanceState之后无法执行此操作-屏幕旋转后 - IllegalStateException: Can not perform this action after onSaveInstanceState - after screen rotating Android - 无法在完成后销毁活动,由 IllegalStateException 引起:在 onSaveInstanceState 后无法执行此操作 - Android - Unable to destroy activity after finish, caused by IllegalStateException: Can not perform this action after onSaveInstanceState
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM