java.lang.IllegalStateException - 在onSaveInstanceState

时间:2017-10-28 11:04:51

标签: android android-fragments android-activity onsaveinstancestate

我收到了来自fabric.io 的以下崩溃报告(主要是在我添加了一个可以从我的SlidingMenue加载到我的应用程序的SettingsActivity之后):

发布pendingRunnable的代码最近没有改变,无论如何它开始收到例外。

Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1842)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1860)
       at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:650)
       at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:609)
       at my.app.ui.activity.MainActivity$2.run(MainActivity.java:271)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5530)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:733)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:623)

这是我的MainActivity.java

 public class MainActivity extends AppCompatActivity implements MyAppFragment.OnListFragmentInteractionListener, AsyncResponse {

        private MyAppDatabaseHandler myAppDatabaseHandler;

        private SharedPreferences sharedpreferences;
        private SharedPreferences defaultPrefs;

        private FragmentA fragmentA;

        public static boolean activityVisible = true;
        private boolean isAttached;

        private NavigationView navigationView;
        private DrawerLayout drawer;
        private View navHeader;
        private Toolbar toolbar;

        // index to identify current nav menu item
        private static int navItemIndex = 0;

        public static String CURRENT_TAG = MyAppConstants.TAG_A;

        // toolbar titles respected to selected nav menu item
        private String[] activityTitles;

        // flag to load home fragment when user presses back key
        private boolean shouldLoadHomeFragOnBackPress = true;
        private Handler mHandler;

        @Override
        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            this.myAppDatabaseHandler= MyAppDatabaseHandler.getInstance(this);
            defaultPrefs = PreferenceManager.getDefaultSharedPreferences(this);

            sharedpreferences = getSharedPreferences(MyAppConstants.PREFERENCES, Context.MODE_PRIVATE);

                setContentView(R.layout.activity_main);

                fragmentA = new FragmentA();

                // Init UI
                toolbar = (Toolbar) findViewById(R.id.toolbar);
                setSupportActionBar(toolbar);

                mHandler = new Handler();

                drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
                navigationView = (NavigationView) findViewById(R.id.nav_view);

                // load toolbar titles from string resources
                activityTitles = getResources().getStringArray(R.array.sliding_menu_item_activity_titles);

                // load nav menu header data
                loadNavHeader();

                // initializing navigation menu
                setUpNavigationView();

                if (savedInstanceState == null) {
                    navItemIndex = 0;
                    CURRENT_TAG = MyAppConstants.TAG_A;
                    loadNextFragment();

            }
        }

        /***
         * Load navigation menu header information
         * like background image, profile image
         * name, website, notifications action view (dot)
         */
        private void loadNavHeader() {
            // Init NavigationHeader
        }

        /***
         * Returns respected fragment that user
         * selected from navigation menu
         */
        private void loadNextFragment() {

            // if user select the current navigation menu again, don't do anything
            // just close the navigation drawer
            if (getSupportFragmentManager().findFragmentByTag( CURRENT_TAG) != null && navItemIndex != 4) {
                drawer.closeDrawers();

                return;
            }

            if (navItemIndex == 4) {
                startActivity(new Intent(MainActivity.this, SettingsActivity.class));
            } else {
                // set toolbar title
                setToolbarTitle();

                // Sometimes, when fragment has huge data, screen seems hanging
                // when switching between navigation menus
                // So using runnable, the fragment is loaded with cross fade effect
                // This effect can be seen in GMail app
                Runnable mPendingRunnable = new Runnable() {
                    @Override
                    public void run() {
                        // update the activity_main_header_with_item content by replacing fragments
                        Fragment fragment = getNextFragment();
                        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
                        fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
                        fragmentTransaction.commit();
                    }
                };

                // If mPendingRunnable is not null, then add to the message queue
                if (mPendingRunnable != null) {
                    mHandler.post(mPendingRunnable);
                }
            }

            //Closing drawer on item click
            drawer.closeDrawers();

            // refresh toolbar menu
            invalidateOptionsMenu();
        }

        private Fragment getNextFragment() {
            switch (navItemIndex) {
                case 0:
                    // home
                    return this.fragmentA;
                case 1:
                    FragmentB fragmentB = new FragmentB();
                    return fragmentB;
                case 2:
                    // About Fragment
                    AboutFragment aboutFragment = new AboutFragment();
                    return aboutFragment;
                case 3:
                    // Licence Fragment
                    LicenceFragment licenceFragment = new LicenceFragment();
                    return licenceFragment;
                default:
                    return this.fragmentA;
            }
        }

        private void setToolbarTitle() {
            getSupportActionBar().setTitle(activityTitles[navItemIndex]);
        }

        private void setUpNavigationView() {
            //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
            navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

                // This method will trigger on item Click of navigation menu
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {

                    //Check to see which item was being clicked and perform appropriate action
                    switch (menuItem.getItemId()) {
                        //Replacing the activity_main_header_with_item content with ContentFragment Which is our Inbox View;
                        case R.id.nav_home:
                            navItemIndex = 0;
                            CURRENT_TAG = MyAppConstants.TAG_A;
                            break;
                        case R.id.nav_recently:
                            navItemIndex = 1;
                            CURRENT_TAG = MyAppConstants.TAG_B;
                            break;
                        case R.id.nav_about_us:
                            navItemIndex = 2;
                            CURRENT_TAG = MyAppConstants.TAG_ABOUT;
                            break;
                        case R.id.nav_licences:
                            navItemIndex = 3;
                            CURRENT_TAG = MyAppConstants.TAG_LICENCES;
                            break;
                        case R.id.nav_settings:
                            navItemIndex = 4;
                            // do not set CURRENT_TAG
                            break;
                        default:
                            navItemIndex = 0;
                    }

                    loadNextFragment();

                    return true;
                }
            });

            ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {

                @Override
                public void onDrawerClosed(View drawerView) {
                    // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                    super.onDrawerClosed(drawerView);
                }

                @Override
                public void onDrawerOpened(View drawerView) {
                    // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
                    super.onDrawerOpened(drawerView);
                }
            };

            //Setting the actionbarToggle to drawer layout
            drawer.setDrawerListener(actionBarDrawerToggle);

            //calling sync state is necessary or else your hamburger icon wont show up
            actionBarDrawerToggle.syncState();
        }

        @Override
        public void onBackPressed() {
            if (drawer.isDrawerOpen(GravityCompat.START)) {
                drawer.closeDrawers();
                return;
            }

            // This code loads home fragment when back key is pressed
            // when user is in other fragment than home
            if (shouldLoadHomeFragOnBackPress && CURRENT_TAG != MyAppConstants.TAG_A) {
                // checking if user is on other navigation menu
                // rather than home
                if (navItemIndex != 0) {
                    navItemIndex = 0;
                    CURRENT_TAG = MyAppConstants.TAG_A;
                    loadNextFragment();

                    return;
                }
            }
            finish();
            super.onBackPressed();
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu);
            // Disable Player Icon in case no player is found on device
            Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, MyAppConstants.MUSIC_APP);
            List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
            if(activities == null || activities.size() <= 0) {
                MenuItem player = menu.findItem(R.id.player);
                if(player != null){
                    player.setVisible(false);
                }
            }
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            return super.onOptionsItemSelected(item);
        }

        public void notifyOnDelete(View v) {
            myAppDatabaseHandler.deleteAll();
        }


        @Override
        public void onListFragmentInteraction(Song item) {

        }

        @Override
        public void processFinish(String output) {
            if (isAttached) {
            ...
            }
        }

        @Override
        public void onAttachedToWindow() {
            isAttached = true;
            super.onAttachedToWindow();
        }

        @Override
        public void onDetachedFromWindow() {
            isAttached = false;
            super.onDetachedFromWindow();
        }

        @Override
        public void onResume() {
            activityVisible = true;
            updateFragmentA();
            super.onResume();
        }

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

        @Override
        protected void onDestroy() {
            super.onDestroy();
        }

        @Override
        protected void onStart() {
            super.onStart();
        }


        public void updateFragmentA() {
            if (CURRENT_TAG == MyAppConstants.TAG_A) {
                Timber.i( "updating FragmentA");
                fragmentA.swap();
            }
        }
    }

有关此问题原因的任何想法?

1 个答案:

答案 0 :(得分:1)

首先尝试setContentView(R.layout.activity_main);而不是执行您的操作

@Override
        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            this.myAppDatabaseHandler= MyAppDatabaseHandler.getInstance(this);
            defaultPrefs = PreferenceManager.getDefaultSharedPreferences(this);

            sharedpreferences = getSharedPreferences(MyAppConstants.PREFERENCES, Context.MODE_PRIVATE);