由于这个项目的首页是类似微信的那种 tab 有四个界面 联系人,消息,动态,设置四个界面,因为有频繁的切换,所以就没有使用replace 和 remve方法。而是通过hide,show方式,这样虽然不会重复创建Fragment了,节省了view重绘的性能问题。 但是这样就容易导致一个问题:就是程序长时间后台导致fragment重叠。
    问题描述:                     app运行的时候,按下home键,然后清理内存。                      或者,按下home之后,打开其他的一些占内存的app,然后把本app的内存挤掉了。
    解决方案:  (这个问题google了很多帖子,发现写的很乱,没几个好用的,后来我就一个个的试验,从两个帖子中找到有用的方法。综合如下:)                     1:给每个Fragment加一个Tag;                     2.在onCreate(Bundle savedInstanceState)中判断Bundle savedInstanceState是否不为空;                     3.不为空则进行find Tag,重新给几个frament赋值。                     

1. 
  
 switch (index) { 
   case 0: 
    // 当点击了消息tab时,改变控件的图片和文字颜色 
    messageImage.setImageResource(R.drawable.message_selected);  
    messageText.setTextColor(Color.WHITE); 
    if (messageFragment == null) { 
     // 如果MessageFragment为空,则创建一个并添加到界面上 
     messageFragment = new MessageFragment(); 
     transaction.add(.content, messageFragment,  
  FRAGMENT_TAG[index] 
  ); 
    } else { 
     // 如果MessageFragment不为空,则直接将它显示出来 
     transaction.show(messageFragment); 
    } 
    break; 
 
 
 
 
 
   2.  3. 
  
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
   super.onCreate(savedInstanceState); 
   requestWindowFeature(Window.FEATURE_NO_TITLE); 
   setContentView(R.layout.activity_main); 
   // 初始化布局元素 
   initViews(); 
 
 
   fragmentManager = getFragmentManager(); 
         if (savedInstanceState != null) { 
             //读取上一次界面Save的时候tab选中的状态 
             selindex=savedInstanceState.getInt( 
  PRV_SELINDEX,selindex 
  ); 
             messageFragment = (MessageFragment) fragmentManager.findFragmentByTag( 
  FRAGMENT_TAG[0] 
  ); 
             contactsFragment = (ContactsFragment) fragmentManager.findFragmentByTag( 
  FRAGMENT_TAG[1] 
  ); 
             newsFragment = (NewsFragment) fragmentManager.findFragmentByTag( 
  FRAGMENT_TAG[2] 
  ); 
             settingFragment = (SettingFragment) fragmentManager.findFragmentByTag( 
  FRAGMENT_TAG[3] 
  ); 
         } 
         // 选中index 
   setTabSelection( 
  selindex 
  ); 
  } 
 
 
 
   //那么文中有几处蓝色高亮的代码  请看如下 
  
 
 
     /** 
      * Fragment的TAG 用于解决app内存被回收之后导致的fragment重叠问题 
      */ 
     private static final  String[] FRAGMENT_TAG = {"msgfrag","contacfrag","actfrag","settfrag"};



PS: PRV_SELINDEX,selindex   是用于恢复上一次界面Save的时候tab选中的状态

@Override 
     protected void onSaveInstanceState(Bundle outState) { 
         //保存tab选中的状态 
         outState.putInt(PRV_SELINDEX,selindex); 
         super.onSaveInstanceState(outState); 
     } 
 
 
 
 
     /** 
      * 上一次界面 onSaveInstanceState 之前的tab被选中的状态 key 和 value 
      */ 
     private static final  String PRV_SELINDEX="PREV_SELINDEX"; 
     private int selindex=0;



OK,当你配置好了tag之后,再addfrag的时候使用了tag,Act执行saveInstancestates 的时候就会自动按tag给你保存frag的状态了。 那么,你如果觉得这种方式不是很好,你这tag也可以不要在add的时候使用,你可以在Act  onSAveInstancestate的时候, 用FragmentMange手动保存, 然后在act,oncreate的时候bundle不为空 就用之前记录的几个tag手动打开。

这是这个act里面的Frag的问题。
2.那么frag中嵌套frag的时候,也是需要保存与恢复的呢?
frag中的frag是子frag,外层的frag是主frag。先这么叫吧,这样好区分。

一样的道理 ,代码都很像,你把主frag当成act,只是getSurpportFragmentManager的时候 ,不用这个方法,有个getChildFragmentManger,大概是这么写的吧,我记不清是getChildFfragmentMnager还是getSurpportChildFragmentmanager了,反正你找下就行了。 这里就不贴代码了,毕竟很act中潜逃frag代码都很像,逻辑都是一样的。
3.有点要注意的是viewpager中潜逃frag,这样的话 记得把Viewpager的缓存数设置为 frag 数目减一。viewpager有个方法是setoffscreenpagelimit方法,可以设置缓存数目,这个方法看viewpager的源码,意思是缓存下来未显示的子控件,所以viewpager肯定是有一个是显示的,其他的要缓存,那么缓存数是 子控件的数目减一。  而且从viewpager的源码上看,这个方法里,最小的数字是1。  缓存数 默认也是1,你不改的话 他会 有一些问题,就是你这边的frag因为没有被缓存 会被自动释放,然后重新新建,有些逻辑执行的就比较多了 。 viewpager内嵌套frag之后,每次pagerAdapger  执行notifychange的时候会有个问题就是特么的,原来的旧的fragment会先释放,执行ondettach   ondestory方法  ,然后重新创建,要注意。