【转】Android中保存Activity的状态
来源:互联网 发布:雷曼2胜利大逃亡mac 编辑:程序博客网 时间:2024/05/14 08:49
例如,如果在activity A启动后,再启动activity B,在某个时刻activityA因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到activityA时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。
关于onSaveInstanceState(),是在函数里面保存一些View有用的数据到一个Parcelable对象并返回。在Activity的onSaveInstanceState(BundleoutState)中调用View的onSaveInstanceState (),返回Parcelable对象,
当系统调用Activity的的onRestoreInstanceState(BundlesavedInstanceState)时,
这就是onSaveInstanceState()和
如果我们没有覆写onSaveInstanceState()方法,此方法的默认实现会自动保存activity中的某些状态数据,比如activity中各种UI控件的状态.。android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法,因此当activity被摧毁和重建时,这些UI控件会自动保存和恢复状态数据.比如EditText控件会自动保存和恢复输入的数据,而CheckBox控件会自动保存和恢复选中状态.开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可),剩余的事情就可以自动完成了.如果没有为控件指定ID, 则这个控件就不会进行自动的数据保存和恢复操作。
由上所述, 如果我们需要覆写onSaveInstanceState()方法,一般会在第一行代码中调用该方法的默认实现:super.onSaveInstanceState(outState)。
5. 是否需要重写onSaveInstanceState()方法
如果需要保存额外的数据时,就需要覆写onSaveInstanceState()方法。大家需要注意的是:onSaveInstanceState()方法只适合保存瞬态数据,比如UI控件的状态,成员变量的值等,而不应该用来保存持久化数据,持久化数据应该当用户离开当前的activity时,在onPause()中保存(比如将数据保存到数据库或文件中)。说到这里,还要说一点的就是在onPause()中不适合用来保存比较费时的数据,所以这点要理解。
由于onSaveInstanceState()方法方法不一定会被调用, 因此不适合在该方法中保存持久化数据,例如向数据库中插入记录等.保存持久化数据的操作应该放在onPause()中。若是永久性值,则在onPause()中保存;若大量,则另开线程吧,别阻塞UI线程。
除了系统处于内存不足的原因会摧毁activity之外, 某些系统设置的改变也会导致activity的摧毁和重建.例如改变屏幕方向(见上例), 改变设备语言设定, 键盘弹出等。
另外,当屏幕的方向发生了改变,Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据。可以重写Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法,如下代码所示:
packagecom.code.test;importandroid.app.Activity;import android.content.pm.ActivityInfo;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity{ privateString message = ""; privateEditText text = null; privateButton button = null; @Override public voidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (EditText) findViewById(R.id.editText1); button = (Button)findViewById(R.id.btnSave); button.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(getApplicationContext(), "保存",Toast.LENGTH_SHORT).show(); } }); } @Override public voidonResume(){ super.onResume(); Toast.makeText(getApplicationContext(), message,Toast.LENGTH_LONG).show(); } @Override public voidonSaveInstanceState(Bundle savedInstanceState){ super.onSaveInstanceState(savedInstanceState); savedInstanceState.putString("message",text.getText().toString()); } @Override public voidonRestoreInstanceState(Bundle savedInstanceState){ super.onRestoreInstanceState(savedInstanceState); message = savedInstanceState.getString("message"); }}
@Override public void onSaveInstanceState(BundlesavedInstanceState) { savedInstanceState.putBoolean("MyBoolean", true); savedInstanceState.putDouble("myDouble", 1.9); // etc. super.onSaveInstanceState(savedInstanceState); } @Override public voidonRestoreInstanceState(BundlesavedInstanceState) { super.onRestoreInstanceState(savedInstanceState); boolean myBoolean=savedInstanceState.getBoolean("MyBoolean"); double myDouble =savedInstanceState.getDouble("myDouble"); }
我们可以用旋转屏幕来测试我们的程序保存状态的能力。因为一般旋转时,activity会被重新执行onCreate()onStart()等操作,程序此时能够保存状态是很重要的。可以考虑使用该方法保存数据。当然了在旋转屏幕时我们除了使用onSaveInstanceState()外,还可以使用onRetainNonConfiguration
@Override public Object onRetainNonConfigurationInstance() { // TODO Auto-generated method stub // 在这里设置需要保存的内容,在切换时不是bundle了,我们可以直接通过object来代替。 return super.onRetainNonConfigurationInstance(); }
在恢复屏幕时可以不使用onRestoreInstanceState(),而使用getLastNonConfigurationI
@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取上次切换屏幕保存的对象 Object obj = getLastNonConfigurationInstance(); }
说到这里了,可能有的人就要问了,既然onSaveInstanceState()和onRetainNonConfiguration
之前在其它网站上看到有的朋友说:"
例如下面代码所示要保存一个复杂的数据:
public class DataHolder { int a; Bitmap b; String s; } @Override public Object onRetainNonConfigurationInstance() { // TODO Auto-generated method stub DataHolder dh = new DataHolder(); dh.a = a; dh.b = b; dh.s = s; return dh; }
不过呢,onRetainNonConfiguration
下面是一个使用onRetainNonConfiguration
package com.rotation.demo; import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.os.SystemClock;import android.util.Log;import android.view.View;import android.widget.ProgressBar;public class RotationAsyncActivity extends Activity { private ProgressBar progressBar=null;// 进度条 private RotationAsyncTask asyncTask=null; // 异步任务类 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); progressBar=(ProgressBar)findViewById(R.id.progress); asyncTask=(RotationAsyncTask)getLastNonConfigurationInstance();// 获取对象 if (asyncTask==null) { asyncTask=new RotationAsyncTask(this); asyncTask.execute(); }else { asyncTask.attach(this); updateProgress(asyncTask.getProgress()); if (asyncTask.getProgress()>=100) { markAsDone(); } } } @Override public Object onRetainNonConfigurationInstance() { asyncTask.detach(); return asyncTask; } private void updateProgress(int progress) { progressBar.setProgress(progress); } private void markAsDone() { findViewById(R.id.completed).setVisibility(View.VISIBLE); } // 异步任务类 private static class RotationAsyncTask extends AsyncTask<Void, Void, Void> { private RotationAsyncActivity activity=null; private int progress=0; public RotationAsyncTask() { // TODO Auto-generated constructor stub } public RotationAsyncTask(RotationAsyncActivity activity) { attach(activity); } @Override protected Void doInBackground(Void... unused) { for (int i=0;i<20;i++) { SystemClock.sleep(500); publishProgress(); } return null; } @Override protected void onProgressUpdate(Void... unused) { if (activity==null) { Log.w("RotationAsyncActivity", "onProgressUpdate()"); }else { progress += 5; activity.updateProgress(progress); } } @Override protected void onPostExecute(Void unused) { if (activity==null) { Log.w("RotationAsyncActivity", "onPostExecute()"); }else { activity.markAsDone(); } } protected void detach() { activity = null; } protected void attach(RotationAsyncActivity activity) { this.activity = activity; } protected int getProgress() { return progress; } }}
我们在运行示例时就会发现,无论怎样旋转屏幕都不会影响进度条的更新与下载,需要解释下的是这里我并没有设置下载功能,以上就是在Android中关于InstanceState保存数据和恢复数据的过程,在这里我想再重复一遍:onSaveInstanceState()和onRestoreInstanceState()机制来保存数据时,它仅在非用户显式的指令杀死应用程序时保存和恢复数据。我们可以使用它在我们的程序中来保存数据,可以作为保存数据的一种方式,但在使用过程中需要注意其使用原理和方法。
转载地址:
http://blog.csdn.net/hn_tzy/article/details/9495101- 【转】Android中保存Activity的状态
- android中保存Activity的状态
- Android中保存Activity的状态
- 关于Android中保存activity的状态的几点学习笔记
- Android中保存界面状态
- Activity中保存状态和数据
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法
- Android中保存和恢复Fragment状态的最好方法android:freezesText属性奇葩记录
- 【Tech-Android-Other】Android中保存界面状态
- TCP连接建立系列 — 服务端接收ACK段(一)
- Android 中页面切换动画函数overridePendingTransition
- [leetcode]Remove Duplicates from Sorted List II
- 正则表达式30分钟入门教程 作者:deerchao
- 1-12-3 - 递归法求最大公约数(自制版)
- 【转】Android中保存Activity的状态
- CGAffineTransformMakeRotation和CGAffineTransformScale
- POJ 1017 解题报告
- 第十二周项目3--输出一个整数的二进制形式
- Building Your First Process with Oracle BPM 11g
- nginx进程和实时控制
- iOS解析---WebView和js交互原理
- date类型转换
- callLater方法