實例探究Android應用編寫時Fragment的生命周期問題
管理fragment的生命周期有些像管理activity的生命周期。Fragment可以生存在三種狀態(tài):
Resumed:
Fragment在一個運行中的activity中并且可見。
Paused:
另一個activity處于最頂層,但是fragment所在的activity并沒有被完全覆蓋(頂層的activity是半透明的或不占據(jù)整個屏幕)。
Stoped:
Fragment不可見。可能是它所在的activity處于stoped狀態(tài)或是fragment被刪除并添加到后退棧中了。此狀態(tài)的fragment仍然存在于內存中。
同樣類似于activity,你可以把fragment的狀態(tài)保存在一個Bundle中,在activity被recreated時就需用到這個東西。你可以在onSaveInstanceState()方法中保存狀態(tài)并在onCreate()或onCreateView()或onActivityCreated()中恢復。
Fragment與Activity的生命周期中最大的不同就是存儲到后退棧中的過程。Activity是在停止時自動被系統(tǒng)壓入停止棧,并且這個棧是被系統(tǒng)管理的;而fragment是被壓入activity所管理的一個后退棧,并且只有你在刪除fragment后并明確調用addToBackStack()方法時才被壓入。
然而,管理fragment的生命周期與管理activity的生命周期極其相似。你所需要去思考的是activity的生命周期如何影響fragment的生命周期。
下面這張Fragment生命周期圖大家應該看得很多了:
但最近在寫PageManager(管理頁面跳轉),發(fā)現(xiàn)切換頁面時,之前的頁面走完onDestoryView就直接onDestory了,回來又重新onCreate,如果用hide和show的方式,都不走生命周期,看了ApiDemo代碼,發(fā)現(xiàn)原因,整理一下.
切換Fragment有兩種方式,一種是add新的,并把舊的hide,另一種是replace.
舊的Fragment為Fragment1,新的是Fragment2,忽略非關鍵生命周期。
使用add方法切換時:
載入Fragment1
Fragment1 onCreate Fragment1 onCreateView Fragment1 onStart Fragment1 onResume
用以下代碼切到Fragment2:
FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.hide(Fragment1); ft.add(R.id.simple_fragment, Fragment2); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit();
Fragment1不走任何生命周期,但會調onHiddenChanged方法
Fragment2 onCreate Fragment2 onCreateView Fragment2 onStart Fragment2 onResume
回到Fragment1,Remove Fragment2:
FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.remove(Fragment2); ft.show(Fragment1); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit();
Fragment1還是不走任何生命周期,調onHiddenChanged方法
Fragment2 onPause Fragment2 onStop Fragment2 onDestoryView Fragment2 onDestory
用這種方法切換,F(xiàn)ragment在隱藏時并不會走onDestoryView,所以顯示時也不會走onCreateView,所有View都一直保存在內存中。
用replace方法:
載入Fragment1生命周期與上面相同:
Fragment1 onCreate Fragment1 onCreateView Fragment1 onStart Fragment1 onResume
切到Fragment2:
FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.simple_fragment, Fragment2); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit();
這次的Fragment1走生命周期了
Fragment1 onPause Fragment1 onStop Fragment1 onDestoryView Fragment1 onDestory Fragment2 onCreate Fragment2 onCreateView Fragment2 onStart Fragment2 onResume
真實打印出來可能是Fragment1和Fragment2混在一起的,可以看到,F(xiàn)ragment1走了onDestory,被完全回收了!
再切回到Fragment1
FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.simple_fragment, Fragment1); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit();
Fragment1 onCreate Fragment1 onCreateView Fragment1 onStart Fragment1 onResume Fragment2 onPause Fragment2 onStop Fragment2 onDestoryView Fragment2 onDestory
Fragment1因為已經(jīng)被回收,又走onCreate,F(xiàn)ragment2被回收。
這兩種方式顯然都不滿足我的需求,且與生命周期圖不同。因為我需要在用戶看見/看不見Fragment時register和unregister BroadcastReceiver之類的東西(onHiddenChanged也能實現(xiàn),但第一次載入顯示,以及銷毀時不會走onHiddenChanged方法),也不希望用戶回到上一個Fragment就重新創(chuàng)建整個Fragment,因為這樣消耗資源。
看了ApiDemo,發(fā)現(xiàn)也是用replace方法,但是,我少了一行:
ft.addToBackStack(null);
在replace時加上這行,可以把原來的Fragment放入棧中,走onDestoryView方法,但不會onDestory,返回時,直接onCreateView,不再onCreate.
返回直接調用popBackStack()方法:
getFragmentManager().popBackStack();
- Android中使用DialogFragment編寫對話框的實例教程
- Android App在ViewPager中使用Fragment的實例講解
- Android中ViewPager實現(xiàn)滑動指示條及與Fragment的配合
- Android App中使用ViewPager+Fragment實現(xiàn)滑動切換效果
- 淺談Android App開發(fā)中Fragment的創(chuàng)建與生命周期
- Android應用開發(fā)中Fragment與Activity間通信示例講解
- Android應用開發(fā)中Fragment間通信的實現(xiàn)教程
- 淺談Android app開發(fā)中Fragment的Transaction操作
- Android app開發(fā)中的Fragment入門學習教程
- 實例講解Android應用開發(fā)中Fragment生命周期的控制
- Android應用開發(fā)中使用Fragment的入門學習教程
- Android應用開發(fā)中Fragment存儲功能的基本用法
- Android學習之Fragment
- 實例探究Android開發(fā)中Fragment狀態(tài)的保存與恢復方法