配置變更導致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()中進行,將每個資源重新分配備用資源的給每個元素。