Состояние экземпляра не восстанавливается/сохраняется правильно

Я пытаюсь сохранить и восстановить логическое поле при изменении ориентации экрана. По какой-то причине поле правильно сохраняется/восстанавливается во время первого изменения ориентации, но когда ориентация возвращается в исходное состояние, значение логического значения неверно при вызове onSaveInstanceState().

Согласно этому ответу, я добавил android:configChanges="orientation" к соответствующему тегу активности в манифесте. Следующий код содержит соответствующие методы, упрощенные для ясности:

public class SignatureActivity extends AppCompactActivity {
    private boolean signaturePadIsEmpty = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String orientation = getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT ? "portrait" : "landscape";
        Log.d(TAG, "onCreate: Orientation is " + orientation + ", signaturePadIsEmpty = " + signaturePadIsEmpty);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        signaturePadIsEmpty = savedInstanceState.getBoolean("SignaturePadIsEmpty");

        String orientation = getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT ? "portrait" : "landscape";
        Log.d(TAG, "onRestoreInstanceState: Orientation is " + orientation + ", signaturePadIsEmpty = " + signaturePadIsEmpty);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("SignaturePadIsEmpty", signaturePadIsEmpty);

        String orientation = getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT ? "portrait" : "landscape";
        Log.d(TAG, "onSaveInstanceState: Orientation is " + orientation + ", signaturePadIsEmpty = " + signaturePadIsEmpty);
    }
}

Вот вывод Logcat, когда я запускаю действие и переключаюсь с портрета на альбомную, а затем с альбомной на портретную:

06-27 11:50:08.037 32656-32656/com.example.www.debug D/SignatureActivity: onCreate: Orientation is portrait, signaturePadIsEmpty = true
06-27 11:50:12.405 32656-32656/com.example.www.debug D/SignatureActivity: onSaveInstanceState: Orientation is landscape, signaturePadIsEmpty = false
06-27 11:50:12.461 32656-32656/com.example.www.debug D/SignatureActivity: onCreate: Orientation is landscape, signaturePadIsEmpty = true
06-27 11:50:12.465 32656-32656/com.example.www.debug D/SignatureActivity: onRestoreInstanceState: Orientation is landscape, signaturePadIsEmpty = false
06-27 11:50:15.068 32656-32656/com.example.www.debug D/SignatureActivity: onSaveInstanceState: Orientation is portrait, signaturePadIsEmpty = true
06-27 11:50:15.131 32656-32656/com.example.www.debug D/SignatureActivity: onCreate: Orientation is portrait, signaturePadIsEmpty = true
06-27 11:50:15.133 32656-32656/com.example.www.debug D/SignatureActivity: onRestoreInstanceState: Orientation is portrait, signaturePadIsEmpty = true

Изменить: проблема оказалась вызвана моей реализацией обработчиков событий панели подписи:

private void initializeLayoutElements(final int orientation) {
    signaturePad = findViewById(R.id.signature_pad);
    signaturePad.setOnSignedListener(new SignaturePad.OnSignedListener() {
        @Override
        public void onStartSigning() {
            signaturePadIsEmpty = false;
        }

        @Override
        public void onSigned() {
        }

        @Override
        public void onClear() {
            signaturePadIsEmpty = true;
        }
    });
}

Метод onClear() вызывался после onRestoreInstanceState() и устанавливал флаг в true. Поскольку решение, опубликованное @SOreadytohelp, ответило на мой первоначальный вопрос, я принимаю их ответ.


person Alex    schedule 27.06.2019    source источник


Ответы (1)


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

Ключ находится в onRestoreInstanceState(), получите Boolean, а в onSaveInstanceState() сохраните Boolean, и вам не нужен этот android:configChanges="orientation в manifest.xml.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    signaturePadIsEmpty = savedInstanceState.getBoolean("SignaturePadIsEmpty");
    tvState.setText(String.valueOf(signaturePadIsEmpty));

}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean("SignaturePadIsEmpty", signaturePadIsEmpty);
}
person Skizo-ozᴉʞS    schedule 27.06.2019
comment
Спасибо за Ваш ответ. Соответствующие строки кода в вашем фрагменте идентичны фрагменту в моем вопросе, поэтому я не уверен, что мне следует делать по-другому. - person Alex; 27.06.2019
comment
Я имею в виду, что если вы не добавите свою manifest.xml в мою демонстрацию, она будет работать идеально, даже если я скопирую ваш код... - person Skizo-ozᴉʞS; 27.06.2019
comment
Я нашел проблему. Похоже, обработчик события onClear() панели для подписи вызывался после восстановления состояния. Я установил флаг signaturePadIsEmpty в true в этом обработчике. ???? - person Alex; 27.06.2019
comment
Извините, нужно было включить эту часть кода. Я предположил, что ошибка связана с тем, как я сохранял/восстанавливал состояние экземпляра. - person Alex; 27.06.2019