上一篇文章中,咱们有提到Activity在屏幕尺寸发生变动时的处理方式,总共有两种:性能优化
一样,这两种方式也同时适用于改变屏幕方向、更改系统语言、甚至输入法等等。 所以,本文也一样适用于改变屏幕方向等状况的处理。
或许你会有疑问:咱们该如何选择合适的处理方式呢?
我给你的答案是:选择最合适的。
这么说好像跟没说同样,别急,给你们举个例子就明白了:
好比更改屏幕方向,由竖屏转换为横屏,若是咱们只有一套布局,符合按比例缩放仍然显示正常的话,咱们大能够选择第2种处理方案。可是若是咱们的横竖屏布局是不一样的,好比系统中的“设置”应用,那么咱们选择第2种处理方案就是不合适的。
下图: bash
这是一个典型的横竖屏分别采用不一样布局的例子。
咱们肯定要采起那种解决方案后,接下来极可能要面对另外一个问题,就是性能瓶颈。
根据前一篇文章的实验结果,在发生横竖屏切换的时候,Activity的生命周期一般会按照以下顺序依次执行:ide
D/MainActivity: onPause
D/MainActivity: onSaveInstanceState
D/MainActivity: onStop
D/MainActivity: onDestroy
D/MainActivity: onCreate
D/MainActivity: onStart
D/MainActivity: onRestoreInstanceState
D/MainActivity: onResume布局
若是咱们在生命周期中作了一些繁重的工做,那么整个Activity在重启的过程当中就会很慢。
要解决这个问题,首先咱们要找Fragment帮忙,由于Bundle并非用来传递大型对象的,并且这个对象还须要序列化和反序列化,如此执行起来就更慢了。
固然,若是你只是保存一些整型或者字符串的话,单纯使用Bundle而不借助Fragment也是能够的,可是这样的场景在实际开发中并不常见。
要借助Fragment来中转对象,咱们采用下面三步走的方式:性能
下面用具体的代码片来演示: 首先来看Fragment类:优化
public class TestFragment extends Fragment {
private MyData data;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public void setData(MyData data) {
this.data = data;
}
public MyData getData() {
return data;
}
}
复制代码
咱们再来看Activity类:ui
public class MyActivity extends Activity {
private TestFragment mTestFragment ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getFragmentManager();
mTestFragment = (TestFragment)fm.findFragmentByTag(“test”);
if (retainedFragment == null) {
mTestFragment = new TestFragment ();
fm.beginTransaction().add(mTestFragment, “test”).commit();
mTestFragment.setData(restoreData());
}
}
@Override
public void onDestroy() {
super.onDestroy();
mTestFragment.setData(saveData());
}
}
复制代码
这里还要特别注意一点:在中转对象数据时,不要传入与Activity紧密相关的对象,好比View,不然会形成内存泄漏。
至此,就完成了对重启Activity方案的性能优化。this