Managing State in an Android Activity(先放上来有时间详解)

<:article id=post-379 class="post-379 lab type-lab status-publish hentry" sizset="false" sizcache01251169072484874="91 208 17">

Managing State in an Android Activity

Flo McCubbin  总结: 翻译完这段老外写的东西 其实有些地方和android developers上说的不太一样 但是有些地方还是挺有收获的 但是我还咩有测试(比如说A activity 保存了状态信息 然后finish A 再startActivity(A)不知能否取出上次保存的信息)还有待验证。

Intro

When Android activities are closed or hidden from view they can lose state information, this article describes how to maintain this information.

 当安卓activity被关闭或者被别的View挡住的时候 这个activity就失去了状态信息(这个股 state information也不知道怎么翻译好),这个文章就是专门来讲一下怎么维护这个状态信息。

What is state information? 什么是状态信息

For an Android activity its state is the property values of the controls currently displayed and any other information which is required to get the activity back to its current condition.

对于安卓的activity来说 它的状态就是整个屏幕显示页面上的数据和界面上的VIew(苟且先这么说吧 太抽象 我感觉说白了就是界面上现实的用户看到的VIew和显示在View上的数据)和其他的一些能够使这个activity再重新显示的必要的信息。

For a simple form application this would just be the text values of the text boxes, the check state of the check boxes etc. For a more complicated application like a game you might need to record the positions, velocities, scores and other data in which case an object orientated approach would probably be better and you would need to store a master object in memory.

 对于一个简单的表单应用程序(有道翻译的)这些必要的信息大概就是文本框里的文字了还有像check box的选中状态等等。对于一个更加复杂的应用比如说游戏 我们可能需要记录位置 速度 分数 和其他的一些信息。

Activity Lifecycle and State Information 生命周期和状态信息

State information is lost when the activity is closed, this is probably fine if this occurs when you have designed it but your activity is sometimes closed automatically eg 状态信息会在activity关闭后丢失,你设计的需求就是关闭这个activity那么 activity关闭后状态信息的丢失对你来说是灭有问题的但是有时候activity会被自动关闭:

  • When the activity is not currently displayed on screen it will often be closed by the Dalvik engine to free memory
  • 当activity没有在屏幕上显示(就是activity不可见 属于后台进程的activity)这个activity会被安卓虚拟机自动关闭一边释放内存。
  • When screen orientation is rotated the activity will be completely closed and destroyed then opened again
  • 当旋转屏幕的时候 activity会彻底关闭消亡再重新走一遍生命周期。

The loss of state information is a problem because it looks like your application has just been started and any information entered by the user has been lost.

状态信息的丢失是一个大问题,就像 你的应用程序刚刚开启 用户在输入框里输了一些数据但是这些输入的信息都丢失了(举例:打开应用输了点文字 然后接了一个电话聊了半小时 挂掉电话 返回到刚才输入的界面 可能activity已经被系统杀死 并且activity自动被重启 但是输入的文字已经看不到了)

For more information see the documentation on the Android Developers website for a detailed explanation of the activity lifecycle.

activity的生命周期 详见android 官方文档。

 

How to Store State Information 怎么保存状态信息。

To solve the problem of lost state information any state information from the activity that needs preserving needs to be stored. There are two common places to store state information:

解决这个丢失状态信息的问题,activity里有俩个地方可以保存。

  1. The saved instance state bundle which can be written to in the handler of theonSaveInstanceState(Bundle) activity event and read out again in the onCreate(Bundle) activity event. 在onSaveInstanceState(Bundle)这里边保存为bundle 然后在onCreat()方法里取出来bundle里保存的状态信息。
  2. The SharedPreferences for the application by writing to the in the onPause() activity event , or some other event, and reading them out again in the onCreate(Bundle) activity event. 在 onPause() 里保存到sharedPreferrence里 在onCreat里边再读出来。

 

Difference Between Storage Spaces 不同存储方式的区别。

When deciding how to store your activity state information you need to consider how long you want to store the data for.

当决定怎么来存储这些activity的状态信息的时候你要考虑这些信息你要存储多久。

  1. To store data only for application lifetime (ie temporarily), use theonSaveInstanceState(Bundle) activity eventThis data will only be held in memory until the application is closed, the data will be available any time that this activity starts within the current lifetime of the application.Explanation: if data is stored here by activity A then the application shows a different activity or rotates the screen (hence closing A) and then returns to A the data can be retrieved to populate the controls. However if the application is closed and opened again the data will be gone and the controls will revert to their default values. 要是保存一些临时暂时的数据(在应用程序生ing周期内的信息)使用theonSaveInstanceState(Bundle) 这些状态信息会保存在内存中,程序进程挂的时候这些保存的状态信息也就没有了。只要是在应用的生命周期内任何时候启动这个activity都能获取到这些状态信息。解释说明:A activity保存了这个activity的状态信息 然后启动了B activity或者说A 被关闭了 只要再重新启动A 这些状态信息也会再取回来的。如果application退出了 一般就是这个进程挂了 那么保存的状态信息就全部没有了。
  2. Example of use: storing text typed in by user and selections making up an order, blog entry, message, etc…用在什么地方:用户输入的文字 信息 日志,用户选择的一个订单。
  3. To store data between application instances (ie permanently) use SharedPreferencesThis data is written to the database on the device and is available all the time.Explanation: if data is stored here then it can always be retrieved to populate the controls if the activity is closed then reopened or even if the application is closed then opened again the data can be retrieved to populate the controls. Even if the device is turned off and then on again this data will be persisted. 要是保存永久性的数据那就使用sharedPrefference 。使用sharedPrefference 只要程序开启 任何时候都会很轻易的获取。
  4. Example of use: storing user logons, preferences, settings etc… 使用的地方:保存用户的登陆信息 设置信息等。

 

Store State in State Bundle 在bundle里保存状态信息。

Override the onSaveInstanceState(Bundle) activity event , get the data that you need to store and add it to the savedInstanceState bundle. In this example the current values of the UI controls are stored.

This event occurs when the activity is about to be closed.

[Code sample – Store State in State Bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();
  
  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();
  
  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();
  
  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);
      
  super.onSaveInstanceState(savedInstanceState);
}

Values are written to the savedInstanceState Bundle using the put**** methods.

 

Load State from State Bundle

In the activity’s onCreate(Bundle) event you can check for values stored in the savedInstanceState Bundle and if present use them to set the values of the controls again.

If there is no corresponding value for a control set it to a default value.

[Code sample – Load State from State Bundle]
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState
{
    super.onCreate(savedInstanceState);
    
  // Restore UI state from the savedInstanceState.
  if (savedInstanceState != null)
  {
    String strValue = savedInstanceState.getString("Name");
    if (strValue != null)
    {
      EditText oControl = (EditText)findViewById(R.id.txtName);
      oControl.setText(strValue);
    }
    
    strValue = savedInstanceState.getString("Email");
    if (strValue != null)
    {
      EditText oControl = (EditText)findViewById(R.id.txtEmail);
      oControl.setText(strValue);
    }
    
    CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
    chkTandC.setChecked(savedInstanceState.getBoolean("TandC"));
  }
}

Values are read from the savedInstanceState Bundle using the get**** methods.

 

Store State in SharedPreferences

The SharedPreferences can be accessed in any event handler of the activity in this example we are overriding the onPause() activity event to store the values before an activity is destroyed.

[Code sample – Store State in SharedPreferences]
@Override
protected void onPause() 
{
  super.onPause();
  
  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();
  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();
  
  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();
  
  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();
  
  editor.putString(“Name”, strName)// value to store
  editor.putString(“Email”, strEmail)// value to store
  editor.putBoolean(“TandC”, blnTandC)// value to store    
  // Commit to storage
  editor.commit();
}

To store values in the SharedPreferences you need to get an instance of an editor , use its put**** methods then call commit().

 

Load State from SharedPreferences

In the activity’s onCreate(Bundle) event you can check for values stored in the SharedPreferences , to read values there is no need to get an instance of an editor .

[Code sample – Load State from SharedPreferences]
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState
{
  super.onCreate(savedInstanceState);
  
  // Get the between instance stored values
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  
  // Set the values of the UI
  EditText oControl = (EditText)findViewById(R.id.txtName);
  oControl.setText(preferences.getString("Name"null));
  
  oControl = (EditText)findViewById(R.id.txtEmail);
  oControl.setText(preferences.getString("Email"null));
  
  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  chkTandC.setChecked(preferences.getBoolean("TandC"false));
}

Use the get**** methods to read the values, if there is no corresponding value for a control set it to a default value.

 

How to Store Object Instances 怎么样保存复杂点的对象。

If you have an object instances that you need to keep alive in memory then you will need to use theonRetainNonConfigurationInstance() activity event to store them.

This is useful for more complicated applications which might be running processes in threads or be managing data in an object orientated way.

Like the use the onSaveInstanceState(Bundle) activity event method of storing state information this will be lost between application instances. If you need to maintain the state of objects between application runtimes then you may want to add methods to your objects to allow them to read and write their data to the device database, files on the SD card, to a remote storage location (perhaps via a webservice) or some other method.

Override the onRetainNonConfigurationInstance() activity event to store a reference to your object instance that will keep it in memory while the application is running.

[Code sample – store object instance]
private cMyClassType moInstanceOfAClass;// Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance() 
{
  if (moInstanceOfAClass != null// Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}

To check for and retrieve the instance that was stored use the getLastNonConfigurationInstance()method.

[Code sample – retrieve object intance]
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState
{
  super.onCreate(savedInstanceState);
   
  // Get the instance of the object that was stored
  // if one exists
  if (getLastNonConfigurationInstance() != null)
  {
    moInstanceOfAClass
(cMyClassType)getLastNonConfigurationInstance();
  }
}
posted @ 2013-03-28 23:02  ITeer  阅读(238)  评论(0编辑  收藏  举报