前面讨论过设备旋转的问题,当设备旋转时配置发生改变,系统默认的是销毁Activtiy,然后再重建Activity,因为新的配置可能需要新的资源。我们可以在AndroidManifest.xml的Activity标签中设置Android:configChanges的属性,然后重载onConfigurationChanged(Configuration),那么指定的配置发生改变时就不会销毁和重建Activity了。也可以设置Activity的android:screenOrientation,那么就设备旋转配置就不会发生改变了。
上面的解决方法中没有销毁和重建Activity,那么我们来研究下设备配置发生改变销毁和重建Activity中Fragment的问题。
首先Fragment的生命周期是受Activity调用的,如果Activity停止且被销毁了,会依次调用Fragment中的函数:
运行中->onPause()->onStop()->onDestroyView()->(不保留)onDestroy()->onDetach()。可以看到Fragment随Activity销毁了。
假如我们在实际项目中遇到这种需求:
Fragment托管在Activity中,Fragment中的MediaPlayer实例进行音频播放,在旋转设备时,Fragment随着Activity的销毁被销毁了,然后在重建,即使我们在销毁时在onSavedInstanceState(Bundle)中保存了MediaPlayer实例,音频的播放也会停止。Fragment的视图,如果我们设置了Fragment的保留,即在代码中设置了setRetainInstance(true).
其实Fragment的在被销毁时的过程是这样的:首先调用onDestroyView()销毁
public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setRetainInstance(true);//保留Fragment }此时该fragment是不会被销毁的,只是游离于Activity之外,当Activity重建时,新创建的FragmentManager会找到被保留的fragment的,并调用fragment的onCreateView()重建视图。
需要主要的地方还有:被保留的fragment其内部的变量和对象也是被保存下来的,我们可以使用,而且fragment的onCreateView()可能会多次调用,假如我们在onCreateView()进行一些对象的创建,那么我们就要避免多次创建他。
比如下面的例子:
public class MyFragment extends Fragment{ public int mIndex; public TextView text; public View cacheView; public MyFragment(int index){ mIndex=index; } @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){ //避免重新创建view if(cacheView!=null){ ViewGroup parent=(ViewGroup)cacheView.getParent(); if(parent!=null){ parent.removeView(cacheView); } return cacheView; } cacheView=inflater.inflate(R.layout.fragmeng_layout, container, false); text=(TextView)cacheView.findViewById(R.id.text); text.setText(String.valueOf(mIndex)); return cacheView; } }
原文地址:http://blog.csdn.net/u010852801/article/details/44199527