Why user input isn't restored via onRestoreInstanceState on Android 10?

46 Views Asked by At

I have this following code:

public class MainActivity extends AppCompatActivity {

    EditText edtInput;
    private static final String STATE_RESULT = "state_result";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        edtInput = (EditText) findViewById(R.id.edtInput);

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putString(STATE_RESULT, edtInput.getText().toString());
        super.onSaveInstanceState(outState);

    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if (savedInstanceState != null){
            edtInput.setText(savedInstanceState.get(STATE_RESULT).toString());
        }
    }
}

On Pixel 3 (running Android 12): type something in the EditText, then do a combo of screen rotations, turning on/off the screen, press back to home and open the app again. the user input is still on EditText

On Xiaomi Pocophone F1 (running Android 10) there's a slightly different behaviour: EditText is cleared if you press back and open the app again. but no problem as long as you only turn on/off or rotate the screen.

Not sure if I misunderstood Android activity lifecycle, or this is a bug on the OS. Any help is appreciated.

1

There are 1 best solutions below

3
user496854 On

Before you can start figuring out why it's happening, you need to figure out what exactly is happening.

You should add some logging to see exactly where it fails. Maybe on the F1, the app gets killed before it calls onSaveInstanceState(). Or maybe onRestoreInstanceState() has savedInstanceState == null:

@Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putString(STATE_RESULT, edtInput.getText().toString());
        super.onSaveInstanceState(outState);
        Log.d("***", "Saved")
    }

@Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("***", "Restoring: " + (savedInstanceState == null))
        if (savedInstanceState != null){
            edtInput.setText(savedInstanceState.get(STATE_RESULT).toString());
        }
    }

And then look at the logs to see what happens on the F1 when you exit the app using the back arrow, and then re-launch it.

Edit: Since it appears that onRestoreInstanceState() isn't being called on the F1, you should probably try to save your app state yourself, instead of relying on savedInstanceState. For example, you can just add an onTextChanged() listener to each of the editText fields, and save the text into SharedPreferences. And you can delete that preference when the user submits the text. You can then restore them in onCreate(). That way, you're completely independent of the lifecycle