【或许会遇到的问题】
当用户旋转设备时,Android通常会销毁并重新创建当前的Activity,你希望能在这个处理周期内一直保存数据,但是在此期间Activity中的所有成员变量都丢失了。
【解决方案】
方案一:如果所有数据都是由基本数据类型构成或者是可序列化的,那么可以将其保存在传入的Bundle中的onSaveInstanceState()当中。
方案二:返回一个任意对象,此时只需要在Activity中改写onRetainNonConfigurationInstance()方法以便于保存一些数据,在onCreate()方法接近末尾处调用getLastNonConfigurationInstance()来看看之前保存的值是否存在,如果是,就可以对应赋值给字段。
onSaveInstanceState():横竖屏切换时触发,用于保持实例状态。
onRetainNonConfigurationInstance():能够保留变化前的状态,并且可以返回一个包含有状态信息的Object;
【示例】
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
saving = false; //成员变量boolean类型变量;
paused = false; //成员变量boolean类型变量;
Main old = (Main)getLastNonConfigurationInstance();
if(old!=null)
{
saving = old.saving;
paused = old.paused;
fileSaver = old.fileSaver;//成员变量-指代文件句柄
if(saving)
{
fileNameLable.setText(fileSaver.getFileName());
}
return;
}
fileSaver = new GPSFileSaver(..............);
}
@Override
public Object onRetainNonConfigurationInstance()
{
return this;
}
上面的代码返回 了Activity的引用,从而使该Activity中的所有成员变量都可以从中进行访问,甚至包括私有成员变量。本案例用到一个FileSaver类来接收来自定位数据服务的数据,希望不管是否发生旋转,都能够连续获取到位置数据并将其保存在磁盘上,而不是每当屏幕旋转时就必须重启定位服务。当Android创建了一个新实例之后,就会调用onCreate()方法发出新实例已经被创建的通知。在onCreate()方法中,通常进行的类似于构造方法中进行的处理。但是需要在接近onCreate()方法的结尾处需要添加一些代码来获取旧实例,并从中获取一些重要的成员变量。
fileSaver是一个重要的对象,我们希望该对象能够持续运行而不必每次重新创建。如果没有旧实例,那么就只能在onCreate()方法的末尾创建fileSaver对象,因为如果不这样的话,我们就要总是仅仅为了用旧的fileSaver对象替换新的fileSaver对象而新建一个fileSaver对象,这对应用程序的性能而言不是什么好事。当onCreate()方法执行结束之后,就不再需要保持对旧实例的引用,因此此时Java就应当对其进行垃圾回收处理。最终结果就是Activity在屏幕上旋转期间看上去一直在好好地持续运行,尽管在此期间Activity已经被重建。
方案三:在AndroidManifest.xml中设置android:configChanges="orientation",该方法避免了Activity被销毁和重建,但是通常也妨碍了应用程序在景观模式下正确显示,Android官方认为不是一种好做法。