糧草先行——Android摺疊屏開發技術點番外篇之運行時變動處理原則

上一篇文章中,咱們有提到Activity在屏幕尺寸發生變動時的處理方式,總共有兩種:性能優化

  1. 重啓APP以適應屏幕改變;
  2. 手動處理數據,避免APP重啓。

一樣,這兩種方式也同時適用於改變屏幕方向、更改系統語言、甚至輸入法等等。
所以,本文也一樣適用於改變屏幕方向等狀況的處理。
或許你會有疑問:咱們該如何選擇合適的處理方式呢?
我給你的答案是:選擇最合適的。
這麼說好像跟沒說同樣,別急,給你們舉個例子就明白了:
好比更改屏幕方向,由豎屏轉換爲橫屏,若是咱們只有一套佈局,符合按比例縮放仍然顯示正常的話,咱們大能夠選擇第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來中轉對象,咱們採用下面三步走的方式:性能

  1. 在Fragment類中調用 setRetainInstance(true);
  2. 在Activity銷燬時向Fragment類存入數據;
  3. 在Activity重建後根據Tag檢索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

相關文章
相關標籤/搜索