I have noticed some things that seem odd to me regarding android's packing/unpacking of view hierarchies. I am hoping someone can clarify things for me.
I understand that any views, provided they have an ID specified will automatically have their state bundled up, Great Ref. here. eg., when the screen rotates and then rotates back, an EditText will automatically have its text set back to what it was. I have a few related questions however:
Why does EditText get its state passed back to onCreate, after onDestroy is called. I don't see a path back from onDestroy to onCreate in the documented activity lifecycle. It seems to me that it could get its state back if it got back to onCreate via onStop, but once onDestroy is called there is no path back to onCreate.
Why won't a TextView remember its state after a screen rotation. This strikes me as being very similar to the EditText having its state restored. I am guessing TextView just wasn't implemented to automatically have its state bundled?
I also noticed that if onDestroy is called by hitting the back button multiple times, and then if I bring back the application, eg, on my phone by longpressing the center button, then selecting the app, the app bundle is not saved. That is both the EditText and the TextViews states are set back to their initial text. This last part makes sense, since onDestroy was called.
It would appear that onDestroy gets called differently when the screen is rotated, vs. when the back button is hit multiple times.
Here is the java source from a simple test app. that I wrote to demonstrate. The layout is just 1 button, 1 textview and 1 editview.
package com.example.sse.activitylifecycle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button btnSetText;
private EditText editText;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null)
Log.i("myFLAG", "onCreate Called. NO BUNDLE PASSED");
else
Log.i("myFLAG", "onCreate Called. BUNDLE PASSED");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
editText = (EditText) findViewById(R.id.editText);
btnSetText = (Button) findViewById(R.id.btnSetText);
btnSetText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editText.setText("Set Text"); //Text remembered, but only after rotation.
textView.setText("Set Text"); //Text NOT remembered.
}
});
}
@Override
protected void onRestart() {
Log.i("myFLAG", "onRestart Called.");
super.onRestart();
}
@Override
protected void onResume() {
Log.i("myFLAG", "onResume Called.");
super.onResume();
}
@Override
protected void onStart() {
Log.i("myFLAG", "onStart Called.");
super.onStart();
}
@Override
protected void onStop() {
Log.i("myFLAG", "onStop Called.");
super.onStop();
}
@Override
protected void onPause() {
Log.i("myFLAG", "onPause Called.");
super.onPause();
}
@Override
protected void onDestroy() {
Log.i("myFLAG", "onDestroy Called.");
super.onDestroy();
}
}
When you're getting a recreation via rotation, its actually creating a whole new Activity. The Activity lifecycle you see diagrams for is for a single Activity. The rotation creates a new one. So there is no path from onDestroy to onCreate, but you're creating a new Activity from scratch with this Bundle variable created by the original Activity.
When hitting the back button, you're finish()ing the Activity. You're exiting it. When you choose to exit an Activity, a Bundle is not saved and the next time you start it we start it with a clean slate. onSaveInstanceState and onRestoreInstanceState are not called. Those are only called when the plan is to recreate the Activity later- when the Activity is killed for resources or configuration change.