android开发中,为了提升性能,我们会用hide()和show(),替代replace(),然而我们进程遇到,使用Fragnment 嵌入到Activity中时,如果遇到bug,app闪退会导致页面的重叠:那么问题来了,为什么使用hide和show的性能会好于replace():
1:使用replace方法把原有的Fragment替换掉;
public class MainActivity extends ActionBarActivity implements OnClickListener
{
private Button ott, tto;
Fragment1 f1;
Fragment2 f2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ott = (Button) findViewById(R.id.ott);
tto = (Button) findViewById(R.id.tto);
ott.setOnClickListener(this);
tto.setOnClickListener(this);
f1 = new Fragment1();
f2 = new Fragment2();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.fl, f1);
ft.commit();
}
@Override
public void onClick(View arg0)
{
if (arg0.getId() == R.id.ott)
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, f2);
ft.commit();
}
else if (arg0.getId() == R.id.tto)
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, f1);
ft.commit();
}
}
}
(1)程序刚刚启动
(2)Fragment1 ——>Fragment2,生命周期为:
(3)Fragment2 ——>Fragment1,生命周期为:
(4)再次Fragment1 ——>Fragment2,生命周期为:
如上,若频繁地replace Fragment来切换,会不断创建新实例,销毁旧的,浪费资源,无法重用。
2、使用hide和show方法,把已经添加过的Fragment隐藏或显示出来。
public class MainActivity extends ActionBarActivity implements OnClickListener
{
private Button ott, tto;
Fragment1 f1;
Fragment2 f2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ott = (Button) findViewById(R.id.ott);
tto = (Button) findViewById(R.id.tto);
ott.setOnClickListener(this);
tto.setOnClickListener(this);
f1 = new Fragment1();
f2 = new Fragment2();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.fl, f1);
ft.commit();
}
@Override
public void onClick(View arg0)
{
if (arg0.getId() == R.id.ott)
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, f2);
ft.commit();
}
else if (arg0.getId() == R.id.tto)
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fl, f1);
ft.commit();
}
}
}
此时情况会发生什么变化呢?
(1)程序刚刚启动
(2)Fragment1 ——>Fragment2,生命周期为:
(3)Fragment2 ——>Fragment1,不打印任何生命周期
(4)再次Fragment1 ——>Fragment2,不打印任何生命周期
使用场景:如果Fragment需要重用或者不断切换,可以使用该方法提高性能。使用使用show和hide会出现重叠
那么如何解决重叠呢:
我找到了原因,在我切换到其他app的时候,fragment所在activity已经被销毁。并且通过
@Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
Log.v("LH", "onSaveInstanceState"+outState);
super.onSaveInstanceState(outState);
}
这个方法保存了相关的数据。
当我再次回到这个app的时候,通过onCreate中的参数savedInstanceState恢复了之前的fragment。此时的FragmentTransaction中的相当于又再次add了fragment进去的,之前保存的fragment也还在。hide()和show()方法对之前保存的fragment已经失效了。所以出现了重叠的现象。
第一种比较方便的解决方法时:
直接在包含Fragment的Activity中复写
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
//Log.v("LH", "onSaveInstanceState"+outState);
//super.onSaveInstanceState(outState); //将这一行注释掉,阻止activity保存fragment的状态
}
第二种保存app崩溃时的数据:
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putString("TAG",tag);
}
//onCreate的时候调用
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState!=null){
tag= savedInstanceState.getString("TAG");
int i = Integer.parseInt(tag);
fragmentTransaction.remove(fragments[i]);
}
}
通过remove把之前的移除掉,建立新的页面:
3.保存app崩溃时的数据:
1.页面切换代码
@Override
public void callTabFragment(int id) {
id2 = id;
tab1=id;
ft = getSupportFragmentManager().beginTransaction();
hide(ft);
switch (id) {
case R.id.home_item_tab:
if (homeFargment == null) {
homeFargment = new HomeFargment();
ft.add(R.id.fl, homeFargment,R.id.home_item_tab+"");
} else {
ft.show(homeFargment);
}
tab=R.id.home_item_tab;
break;
case R.id.shaidan_item_tab:
if (shaidanFargment == null) {
shaidanFargment = new JiaMengFargment();
ft.add(R.id.fl, shaidanFargment,R.id.shaidan_item_tab+"");
} else {
ft.show(shaidanFargment);
}
tab=R.id.shaidan_item_tab;
break;
case R.id.gwc_item_tab:
if (gwcFargment == null) {
gwcFargment = new GwcFargment();
ft.add(R.id.fl, gwcFargment,R.id.gwc_item_tab+"");
} else {
ft.show(gwcFargment);
}
tab=R.id.gwc_item_tab;
break;
case R.id.my_item_tab:
if (meFargment == null) {
meFargment = new MeFargment();
ft.add(R.id.fl, meFargment,R.id.my_item_tab+"");
} else {
ft.show(meFargment);
}
tab=R.id.my_item_tab;
break;
}
ft.commit();
}
2.保存崩溃前的数据:
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
//super.onSaveInstanceState(outState);
outState.putInt("tab1", tab1);
outState.putInt("tab", tab);
}
3.恢复数据
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
if (savedInstanceState!=null) {
tab=savedInstanceState.getInt("tab");
callTabFragment(tab);
//切换背景
}
super.onRestoreInstanceState(savedInstanceState);
}