Как узнать, был ли вызван метод onSaveInstanceState(), чтобы избежать исключения IllegalStateException?

Когда пользователь выбирает элемент в навигационном ящике, мое приложение запускает обработчик, который, дождавшись закрытия ящика, вызывает код для замены фрагмента в моем основном действии. Однако, если устройство было повернуто во время задержки, я получаю исключение IllegalStateException.

Я прочитал эту блестящую статью о транзакциях и жизненных циклах фрагментов, но я не уверен, как справиться с этим в моем коде. Я понимаю, что не должен пытаться совершить транзакцию после onSaveInstanceState(). Но как я узнаю, был ли вызван onSaveInstanceState()? Я хочу сделать что-то вроде этого.

navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(final MenuItem menuItem) {
        // close drawers
        drawerLayout.closeDrawers();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                goTo(menuItem); // swap in Fragment specified by menuItem
            }
        }, 300);
        return true;
    }
    });
...
private void goTo(menuItem) {
    if( alreadyCalledOnSaveInstanceState() {  // THIS
        return;
    }

    switch (item.getItemId()) {
        case R.id.item1:
            frag = new Fragment_Grade_Calculator();
            getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_up, R.anim.zoom_exit).replace(R.id.main_frag_container, frag)
                    .commit();
            return true;
}

Но я не знаю эквивалента моему выдуманному alreadyCalledOnSaveInstanceState().


person NSouth    schedule 09.11.2015    source источник
comment
В итоге я просто поставил try/catch вокруг моего вызова goTo(menuItem). Это сработало для моих целей - фрагмент никогда не меняется местами. Лучше, чем разбиться.   -  person NSouth    schedule 09.11.2015


Ответы (2)


Я думаю, вам следует использовать не onSaveInstanceState(), а onStop(). И не совершайте транзакцию после вызова onStop(). И не забудьте разрешить фиксацию вашей транзакции после вызова onStart().

person ivan    schedule 09.11.2015
comment
Вы говорите, что я должен вручную отслеживать, были ли вызваны onSaveInstanceState() или onStop()? - person NSouth; 09.11.2015
comment
Эта статья посвящена вашей проблеме: androiddesignpatterns.com/ 2013/08/ - person ivan; 10.11.2015

Насколько я знаю, onSaveInstanceState() никогда не будет вызываться до onPause(). Поэтому, пока вы фиксируете транзакции фрагментов в возобновленном состоянии, вы должны быть в безопасности от попадания в исключение IllegalStateException.

person nolanic    schedule 28.01.2021
comment
Согласно документам, после android P onSaveInstanceState гарантированно вызывается после onStop. Но до Android P onSaveInstanceState будет вызываться перед onStop, и нет гарантии, произойдет ли это до или после onPause. developer.android.com/reference/android/app / - person eliasbagley; 27.03.2021