Handling runtime changes(一)使用Fragment来保持之前的数据
转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/24271657
在运行应用程序的时候,设备的一些configuration可能会发生变化(比如屏幕方向,键盘,语言等等)。当这些变化发生的时候,Android会重新启动你的Activity,这样就能让你的应用程序根据新的configuration显示正确的信息。Android提供了onSaveInstance来保存一些状态信息,从而在重新启动Activity的时候能够根据这些状态信息显示出之前的Activity。我们可以在onCreate或者onRestoreInstanceState的时候来还原这些信息。
但是有的时候重新启动Activity可能需要恢复大量的数据,或者重新建立网络连接等等,这样,用户体验可能不是很好。并且,有可能你不能完全的通过Bundle来还原你之前Activity的状态,因为onSaveInstanceState并不是为保存大数据对象而设计的,比如bitmap,这些数据需要被序列化,然后再被反序列化,导致在configuration change的时候消耗大量的内存,从而变得很慢。这种情况下,你可以通过retain 一个Fragment来减轻重新启动Activity时候的负担。
当系统因为configuration change重新启动你的Activity的时候,这个被设置了reatin为true的fragment不会被销毁。你可以通过添加这种Fragment来保存一些状态数据。
关键方法:
setRetainInstance(true);
public class FragmentA extends Fragment {
privateString data = "";
@Override
publicvoid onAttach(Activity activity) {
super.onAttach(activity);
Log.d("==========","FragmentA onAttach:" + this);
}
@Override
publicvoid onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("==========","FragmentA onActivityCreated");
setRetainInstance(true);
}
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("==========","FragmentA onCreate");
}
@Override
publicView onCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState) {
Log.d("==========","FragmentA onCreateView");
returninflater.inflate(R.layout.fragment_main, container, false);
}
@Override
publicvoid onDestroy() {
super.onDestroy();
Log.d("==========","FragmentA onDestroy");
}
@Override
publicvoid onDestroyView() {
super.onDestroyView();
Log.d("==========","FragmentA onDestroyView");
}
@Override
public voidonDetach() {
super.onDetach();
Log.d("==========","FragmentA onDetach");
}
@Override
publicvoid onPause() {
super.onPause();
Log.d("==========","FragmentA onPause");
}
@Override
publicvoid onResume() {
super.onResume();
Log.d("==========","FragmentA onResume");
}
@Override
publicvoid onStart() {
super.onStart();
Log.d("==========","FragmentA onStart");
}
@Override
publicvoid onStop() {
super.onStop();
Log.d("==========","FragmentA onStop");
}
@Override
publicvoid onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("==========","FragmentA onSaveInstanceState");
}
publicvoid setData(String data) {
this.data= data;
}
}
运行程序,打印Log:
============启动Activity
04-21 19:58:05.079: D/==========(15311):MainActivity onCreate
04-21 19:58:05.099: D/==========(15311):MainActivity onCreate finish
04-21 19:58:05.099: D/==========(15311):MainActivity onStart
04-21 19:58:05.099: D/==========(15311):MainActivity onStart finish
04-21 19:58:05.099: D/==========(15311):MainActivity onResume
04-21 19:58:05.099: D/==========(15311):MainActivity onResume finish
============点击按钮添加Fragment A到当前Activity的Layout中
04-21 19:58:11.989: D/==========(15311):Add Fragment
04-21 19:58:11.999: D/==========(15311):FragmentA onAttach:FragmentA{429f56b8 #0 id=0x7f05003c Fragment A}
04-21 19:58:11.999: D/==========(15311):FragmentA onCreate
04-21 19:58:11.999: D/==========(15311):FragmentA onCreateView
04-21 19:58:11.999: D/==========(15311):FragmentA onActivityCreated
04-21 19:58:11.999: D/==========(15311):FragmentA onStart
04-21 19:58:11.999: D/==========(15311):FragmentA onResume
============旋转屏幕导致重新启动Activity
04-21 19:58:13.949: D/==========(15311):MainActivity onPause
04-21 19:58:13.959: D/==========(15311):FragmentA onPause
04-21 19:58:13.959: D/==========(15311):MainActivity onPause finish
04-21 19:58:13.959: D/==========(15311):MainActivity onSaveInstanceState
04-21 19:58:13.959: D/==========(15311):FragmentA onSaveInstanceState
04-21 19:58:13.959: D/==========(15311):MainActivity onSaveInstanceState finish
04-21 19:58:13.959: D/==========(15311):MainActivity onStop
04-21 19:58:13.959: D/==========(15311):FragmentA onStop
04-21 19:58:13.959: D/==========(15311):MainActivity onStop finish
04-21 19:58:13.959: D/==========(15311):MainActivity onDestroy
04-21 19:58:13.959: D/==========(15311):FragmentA onDestroyView
04-21 19:58:13.959: D/==========(15311):FragmentA onDetach
04-21 19:58:13.959: D/==========(15311):MainActivity onDestroy finish
04-21 19:58:13.969: D/==========(15311):FragmentA onAttach:FragmentA{429f56b8 #0 id=0x7f05003c Fragment A}
04-21 19:58:13.969: D/==========(15311):MainActivity onCreate
04-21 19:58:13.989: D/==========(15311):MainActivity onCreate finish
04-21 19:58:13.989: D/==========(15311):MainActivity onStart
04-21 19:58:13.989: D/==========(15311):FragmentA onCreateView
04-21 19:58:13.989: D/==========(15311):FragmentA onActivityCreated
04-21 19:58:13.989: D/==========(15311): FragmentAonStart
04-21 19:58:13.989: D/==========(15311):MainActivity onStart finish
04-21 19:58:13.989: D/==========(15311):MainActivity onResume
04-21 19:58:13.989: D/==========(15311):MainActivity onResume finish
04-21 19:58:13.989: D/==========(15311):FragmentA onResume
04-21 19:58:14.019: E/ViewRootImpl(15311):sendUserActionEvent() mView == null
分析上面的log可以看出,虽然FragmentA在旋转屏幕的时候依然经历了他的onDestroyView等,但是没有经历onDestroy,onCreate,查看FragmentA的地址两次都是429f56b8,说明这个Fragment没有被重新创建,只是调用了生命周期的一部分回调让它来适应新的configuration。
以下是没有设置true的log:
============启动Activity
04-21 20:06:31.569: D/==========(16064):MainActivity onCreate
04-21 20:06:31.589: D/==========(16064):MainActivity onCreate finish
04-21 20:06:31.589: D/==========(16064):MainActivity onStart
04-21 20:06:31.589: D/==========(16064):MainActivity onStart finish
04-21 20:06:31.589: D/==========(16064):MainActivity onResume
04-21 20:06:31.589: D/==========(16064):MainActivity onResume finish
============点击按钮添加Fragment A到当前Activity的Layout中
04-21 20:06:33.269: D/==========(16064):Add Fragment
04-21 20:06:33.279: D/==========(16064):FragmentA onAttach:FragmentA{429edf58 #0 id=0x7f05003c Fragment A}
04-21 20:06:33.279: D/==========(16064):FragmentA onCreate
04-21 20:06:33.279: D/==========(16064):FragmentA onCreateView
04-21 20:06:33.279: D/==========(16064):FragmentA onActivityCreated
04-21 20:06:33.279: D/==========(16064):FragmentA onStart
04-21 20:06:33.279: D/==========(16064):FragmentA onResume
============旋转屏幕导致重新启动Activity
04-21 20:06:36.089: D/==========(16064):MainActivity onPause
04-21 20:06:36.089: D/==========(16064):FragmentA onPause
04-21 20:06:36.089: D/==========(16064):MainActivity onPause finish
04-21 20:06:36.089: D/==========(16064):MainActivity onSaveInstanceState
04-21 20:06:36.089: D/==========(16064):FragmentA onSaveInstanceState
04-21 20:06:36.089: D/==========(16064):MainActivity onSaveInstanceState finish
04-21 20:06:36.089: D/==========(16064):MainActivity onStop
04-21 20:06:36.089: D/==========(16064):FragmentA onStop
04-21 20:06:36.089: D/==========(16064):MainActivity onStop finish
04-21 20:06:36.089: D/==========(16064):MainActivity onDestroy
04-21 20:06:36.089: D/==========(16064):FragmentA onDestroyView
04-21 20:06:36.099: D/==========(16064): FragmentA onDestroy
04-21 20:06:36.099: D/==========(16064):FragmentA onDetach
04-21 20:06:36.099: D/==========(16064):MainActivity onDestroy finish
04-21 20:06:36.099: D/==========(16064):FragmentA onAttach:FragmentA{429f3640 #0 id=0x7f05003c Fragment A}
04-21 20:06:36.099: D/==========(16064): FragmentA onCreate
04-21 20:06:36.099: D/==========(16064):MainActivity onCreate
04-21 20:06:36.119: D/==========(16064):MainActivity onCreate finish
04-21 20:06:36.119: D/==========(16064):MainActivity onStart
04-21 20:06:36.119: D/==========(16064):FragmentA onCreateView
04-21 20:06:36.119: D/==========(16064):FragmentA onActivityCreated
04-21 20:06:36.119: D/==========(16064):FragmentA onStart
04-21 20:06:36.119: D/==========(16064):MainActivity onStart finish
04-21 20:06:36.119: D/==========(16064):MainActivity onResume
04-21 20:06:36.119: D/==========(16064):MainActivity onResume finish
04-21 20:06:36.119: D/==========(16064):FragmentA onResume