一.在Fragment中存储Activity的数据(在配置变更导致Activity重启情况下)
在关闭Activity的时候,你希望能把页面上的数据存储下来,很多人第一反应一定是onSaveInstanceState()这个方法。对,一般情况下我们几乎都是用的这个方法,但是像系统配置变化导致Activity重启的情况,我们还可以使用另外一种方式,Fragment,碎片。
当然在系统配置变化导致的重启的时候,我们也可以使用onSaveInstanceSate()这种方式来存储。但是,onSaveInstanceState()最好不用用于携带大型对象上。它存储数据和读取数据,会先把其中的数据进行序列化,再经过反序列化,这其中会消耗大量内存,会使配置速度变得缓慢。这种情况下,我们可以使用保留Fragment,来减轻Activity的负担。
接下来我们看看应该怎么写。先创建Fragment和一个数据类-MyDataObject。
public class RetainedFragment extends Fragment {
private MyDataObject data;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);//这一步是必须的
}
public void setData(MyDataObject data) {
this.data = data;
}
public MyDataObject getData(){
return data;
}
}
随后在Activity中调用
public class MyActivity extends Activity {
private RetainedFragment retainedFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager=getFragmentManager();
retainedFragment= (RetainedFragment) fragmentManager.findFragmentByTag("data");
if(retainedFragment==null){
retainedFragment=new RetainedFragment();
fragmentManager.beginTransaction().add(retainedFragment,"data").commit();
retainedFragment.setData(loadData());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
retainedFragment.setData(collectionMyLoadedData());
}
//获取的数据,从保存的里面获取的
private MyDataObject loadData(){
return null;
}
//此刻需要被保存的数据
private MyDataObject collectionMyLoadedData(){
return null;
}
}
*注意:可以存储任何对象,但是不能传递Activity绑定的对象,比如:Adapter,View,或者其他与Context相关的对象。否则会泄漏原始Activity实例的所有视图和资源。
而泄漏资源代表:应用将继续持有这些资源,无法对其进行垃圾回收处理,会丢失大量内存。
二.自行处理配置变更
对于配置变更导致的Activity重启,我们可以从根源上解决这个问题,也就是——自行处理配置变更,避免Activity的重启。但Android官方是不建议大多数应用使用这个的。理由如下:
自行处理配置变更可能导致备用资源的使用更为困难,因为系统不会为您自动应用这些资源。(注意)
以下清单文件代码声明Activity可同时处理屏幕方向变更和键盘可用性变更。
这样修改后,键盘,屏幕方向变更的时候,Activity不会再重启,但是在MainActivity中我们会发现,它会调用onConfigurationChanged()
这个方法。这个方法传递Configuration对象指定的配置信息,根据Configuration来获取当前Activity的配置信息。
如果有些操作是需要在屏幕方向变更后/键盘变更后,要做的操作就放在onConfigurationChanged()中进行,将每个资源重新分配备用资源的给每个元素。