2014-09-10 70 views
1

我想了解Android應用程序的總流量,我遇到了我認爲是一個奇怪的情況(注:我非常新的android編程)。應用程序保存方向更改文本框狀態?

我用多行編輯文本字段做了一個測試應用程序。我在場上寫了1234。沒有其他任何東西,對默認的Eclipse ADT所做的應用程序沒有其他更改,也沒有在後端專門重寫任何東西,我改變了方向。 1234仍然存在。然後,我點擊主頁按鈕,然後從最近的應用程序中打開它。 1234仍然存在。

我對應用程序生命週期的理解是應用程序在按下主頁按鈕時停止並啓動,並且在應用程序的方向發生更改時應用程序被銷燬並創建。如果這是正確的,是否有某種形式的自動狀態保持發生?我的假設是我必須從狀態包中抽取個體變量並自行恢復它們。這是不正確的?

任何解釋說,一個更經驗豐富的Android開發人員可以給予的將是偉大的。我一直在試圖找到合適的答案,但無濟於事。

MainActivity.java

package com.example.teststate; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 


public class MainActivity extends Activity { 

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


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == R.id.action_settings) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

activity_main.xml中

<RelativeLayout 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" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.teststate.MainActivity" > 

    <EditText 
     android:id="@+id/editText1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginTop="30dp" 
     android:ems="10" 
     android:inputType="textMultiLine" > 

     <requestFocus /> 
    </EditText> 

</RelativeLayout> 

片段從的Manifest.xml

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

謝謝你!

回答

3

發生這種情況的原因是因爲視圖明確地保存並恢復其方向更改狀態,方法是重寫View#onSaveInstanceState()View#onRestoreInstanceStance(Parcelable)。下面是執行的TextView的(超一流的EditText上

@Override 
public Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 

    // Save state if we are forced to 
    boolean save = mFreezesText; 
    int start = 0; 
    int end = 0; 

    if (mText != null) { 
     start = getSelectionStart(); 
     end = getSelectionEnd(); 
     if (start >= 0 || end >= 0) { 
      // Or save state if there is a selection 
      save = true; 
     } 
    } 

    if (save) { 
     SavedState ss = new SavedState(superState); 
     // XXX Should also save the current scroll position! 
     ss.selStart = start; 
     ss.selEnd = end; 

     if (mText instanceof Spanned) { 
      Spannable sp = new SpannableStringBuilder(mText); 

      if (mEditor != null) { 
       removeMisspelledSpans(sp); 
       sp.removeSpan(mEditor.mSuggestionRangeSpan); 
      } 

      ss.text = sp; 
     } else { 
      ss.text = mText.toString(); 
     } 

     if (isFocused() && start >= 0 && end >= 0) { 
      ss.frozenWithFocus = true; 
     } 

     ss.error = getError(); 

     return ss; 
    } 

    return superState; 
} 

[...] 

@Override 
public void onRestoreInstanceState(Parcelable state) { 
    if (!(state instanceof SavedState)) { 
     super.onRestoreInstanceState(state); 
     return; 
    } 

    SavedState ss = (SavedState)state; 
    super.onRestoreInstanceState(ss.getSuperState()); 

    // XXX restore buffer type too, as well as lots of other stuff 
    if (ss.text != null) { 
     setText(ss.text); 
    } 

    if (ss.selStart >= 0 && ss.selEnd >= 0) { 
     if (mText instanceof Spannable) { 
      int len = mText.length(); 

      if (ss.selStart > len || ss.selEnd > len) { 
       String restored = ""; 

       if (ss.text != null) { 
        restored = "(restored) "; 
       } 

       Log.e(LOG_TAG, "Saved cursor position " + ss.selStart + 
         "/" + ss.selEnd + " out of range for " + restored + 
         "text " + mText); 
      } else { 
       Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd); 

       if (ss.frozenWithFocus) { 
        createEditorIfNeeded(); 
        mEditor.mFrozenWithFocus = true; 
       } 
      } 
     } 
    } 

    if (ss.error != null) { 
     final CharSequence error = ss.error; 
     // Display the error later, after the first layout pass 
     post(new Runnable() { 
      public void run() { 
       setError(error); 
      } 
     }); 
    } 
} 

正如你所看到的,它保存在一個Parcelable對象,然後沿着一個視圖具有相同android:id通過了國家在新實例中,並且onRestoreInstanceState()在新視圖上被調用。如果您創建的自定義視圖不僅包含其他視圖,還可能要覆蓋這些方法。

+0

這是完美的。正確回答我的問題。 – 2014-09-10 22:29:02

2

我無法給你一個代碼級別的解釋。但這是android承諾要做的事情之一。你可以看看這個Recreating activity

注意:爲了讓Android系統恢復活動中視圖的狀態,每個視圖都必須有一個由android:id屬性提供的唯一ID。

相關問題