1. 程式人生 > >配置變更導致Activity重啟——Fragment儲存以及不重啟Activity做法

配置變更導致Activity重啟——Fragment儲存以及不重啟Activity做法

一.在Fragment中儲存Activity的資料(在配置變更導致Activity重啟情況下)       

在關閉Activity的時候,你希望能把頁面上的資料儲存下來,很多人第一反應一定是onSaveInstanceState()這個方法。對,一般情況下我們幾乎都是用的這個方法,但是像系統配置變化導致Activity重啟的情況,我們還可以使用另外一種方式,Fragment,碎片。

    當然在系統配置變化導致的重啟的時候,我們也可以使用onSaveInstanceSate()這種方式來儲存。但是,onSaveInstanceState()最好不用用於攜帶大型物件上。它儲存資料和讀取資料,會先把其中的資料進行序列化,再經過反序列化,這其中會消耗大量記憶體,會使配置速度變得緩慢。這種情況下,我們可以使用保留Fragment,來減輕Activity的負擔。

接下來我們看看應該怎麼寫。先建立Fragment和一個數據類-MyDataObject。


public class RetainedFragment extends Fragment {

    private MyDataObject data;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);//這一步是必須的
    }

    public void setData(MyDataObject data) {
        this.data = data;
    }

    public MyDataObject getData(){
        return data;
    }

}

隨後在Activity中呼叫


public class MyActivity extends Activity {

    private RetainedFragment retainedFragment;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FragmentManager fragmentManager=getFragmentManager();
        retainedFragment= (RetainedFragment) fragmentManager.findFragmentByTag("data");
        if(retainedFragment==null){
            retainedFragment=new RetainedFragment();
            fragmentManager.beginTransaction().add(retainedFragment,"data").commit();
            retainedFragment.setData(loadData());
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        retainedFragment.setData(collectionMyLoadedData());
    }

    //獲取的資料,從儲存的裡面獲取的
    private MyDataObject loadData(){
        return null;
    }

    //此刻需要被儲存的資料
    private MyDataObject collectionMyLoadedData(){
        return null;
    }
}

*注意:可以儲存任何物件,但是不能傳遞Activity繫結的物件,比如:Adapter,View,或者其他與Context相關的物件。否則會洩漏原始Activity例項的所有檢視和資源。

而洩漏資源代表:應用將繼續持有這些資源,無法對其進行垃圾回收處理,會丟失大量記憶體。

 

二.自行處理配置變更

對於配置變更導致的Activity重啟,我們可以從根源上解決這個問題,也就是——自行處理配置變更,避免Activity的重啟。但Android官方是不建議大多數應用使用這個的。理由如下:

自行處理配置變更可能導致備用資源的使用更為困難,因為系統不會為您自動應用這些資源。(注意)

以下清單檔案程式碼宣告Activity可同時處理螢幕方向變更和鍵盤可用性變更。

這樣修改後,鍵盤,螢幕方向變更的時候,Activity不會再重啟,但是在MainActivity中我們會發現,它會呼叫onConfigurationChanged() 這個方法。這個方法傳遞Configuration物件指定的配置資訊,根據Configuration來獲取當前Activity的配置資訊。

如果有些操作是需要在螢幕方向變更後/鍵盤變更後,要做的操作就放在onConfigurationChanged()中進行,將每個資源重新分配備用資源的給每個元素。