上一篇文章中,咱們有提到Activity在屏幕尺寸發生變動時的處理方式,總共有兩種:性能優化
一樣,這兩種方式也同時適用於改變屏幕方向、更改系統語言、甚至輸入法等等。
所以,本文也一樣適用於改變屏幕方向等狀況的處理。
或許你會有疑問:咱們該如何選擇合適的處理方式呢?
我給你的答案是:選擇最合適的。
這麼說好像跟沒說同樣,別急,給你們舉個例子就明白了:
好比更改屏幕方向,由豎屏轉換爲橫屏,若是咱們只有一套佈局,符合按比例縮放仍然顯示正常的話,咱們大能夠選擇第2種處理方案。可是若是咱們的橫豎屏佈局是不一樣的,好比系統中的「設置」應用,那麼咱們選擇第2種處理方案就是不合適的。
下圖:
這是一個典型的橫豎屏分別採用不一樣佈局的例子。
咱們肯定要採起那種解決方案後,接下來極可能要面對另外一個問題,就是性能瓶頸。
根據前一篇文章的實驗結果,在發生橫豎屏切換的時候,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類:this
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方案的性能優化。rest