Reputation: 844
I created a sample application in Android Studio to learn about the life cycle of an Android application. I know that orientation change completely restarts the activity (i.e. OnCreate method is called again). As far as I know, orientation change should have destroyed the context and shown a blank text after device rotation. But somehow without overriding onSaveInstanceState and onRestoreInstanceState methods it is saving the context.
I don't have any fragments. It just the basic template that is provided by Android studio, with few overridden life cycle methods. Here is my MainActivity class:
package com.example.android.a2_screen_orientation_change;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "in method onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "in method onResume");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "in method onRestart");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "in method onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "in method onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "in method onDestroy");
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.a2_screen_orientation_change.MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
AbdroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.a2_screen_orientation_change">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Upvotes: 10
Views: 4836
Reputation: 1179
Android automatically handles saving the state & restoring until you explicitly specify the
android:configChanges="orientation"
in your mainifest
In case, you do not have an id
for the ui element, Android will not be able to restore the state of the element.
Please refer to the answer here https://stackoverflow.com/a/19234974/1099156
Upvotes: 1
Reputation: 264
Because the EditText is a focused view, so in PhoneWindow
, it's state will be saved automatically in saveHierarchyState()
method. You can see the code:
@Override
public Bundle saveHierarchyState() {
Bundle outState = new Bundle();
if (mContentParent == null) {
return outState;
}
SparseArray<Parcelable> states = new SparseArray<Parcelable>();
mContentParent.saveHierarchyState(states);
outState.putSparseParcelableArray(VIEWS_TAG, states);
// save the focused view id
View focusedView = mContentParent.findFocus();
if (focusedView != null) {
if (focusedView.getId() != View.NO_ID) {
outState.putInt(FOCUSED_ID_TAG, focusedView.getId());
} else {
if (false) {
Log.d(TAG, "couldn't save which view has focus because the focused view "
+ focusedView + " has no id.");
}
}
}
// save the panels
SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>();
savePanelState(panelStates);
if (panelStates.size() > 0) {
outState.putSparseParcelableArray(PANELS_TAG, panelStates);
}
if (mActionBar != null) {
outState.putBoolean(ACTION_BAR_TAG, mActionBar.isOverflowMenuShowing());
}
return outState;
}
and the code in TextView
:
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
// Save state if we are forced to
final boolean freezesText = getFreezesText();
boolean hasSelection = false;
int start = -1;
int end = -1;
if (mText != null) {
start = getSelectionStart();
end = getSelectionEnd();
if (start >= 0 || end >= 0) {
// Or save state if there is a selection
hasSelection = true;
}
}
if (freezesText || hasSelection) {
SavedState ss = new SavedState(superState);
if (freezesText) {
if (mText instanceof Spanned) {
final Spannable sp = new SpannableStringBuilder(mText);
if (mEditor != null) {
removeMisspelledSpans(sp);
sp.removeSpan(mEditor.mSuggestionRangeSpan);
}
ss.text = sp;
} else {
ss.text = mText.toString();
}
}
if (hasSelection) {
// XXX Should also save the current scroll position!
ss.selStart = start;
ss.selEnd = end;
}
if (isFocused() && start >= 0 && end >= 0) {
ss.frozenWithFocus = true;
}
ss.error = getError();
if (mEditor != null) {
ss.editorState = mEditor.saveInstanceState();
}
return ss;
}
return superState;
}
So, if you remove the id of the EditTextView in your xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.a2_screen_orientation_change.MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
You will see what you want! (Tanks for supplement from @Mike M.)
Upvotes: 6
Reputation: 927
Android is by default, restoring the state of some Views.
In your Layout xml, add android:saveEnabled="false"
to your EditText. And the value of EditText will not be retained.
Upvotes: 2