1. 程式人生 > >Activit、Fragment的生命週期 及橫豎屏切換的一些問題 及解決方案

Activit、Fragment的生命週期 及橫豎屏切換的一些問題 及解決方案

Activity 的生命週期:

1.onCreate():表示Activity 正在被建立 第一個方法
載入一些介面佈局檔案,初始化Activity

2.onRestart(): 重新啟動

3.onStart():當前Activity 正在啟動 即將開始 已經可見了。還沒有出現在前臺還無法與使用者進行互動

4.onResume(): 表示已經可見了。已經可以和使用者進行互動了

5.onPause(): 表示已經停止了,acitivity 已經不可見了,正常情況下 下面會呼叫OnStop的方法 如果快速呼叫的話 會回到當前的Activity 中

6.onStop(): 即將停止 可以做一些稍微重量級的回收工作,不能做太耗時的工作

7.onDestroy(): 表示Activity即將被銷燬 這是activity生命週期中最後一個回撥 可以做些一些回收工作和最終的資源釋放

橫豎屏切換Activity的時候走的生命週期:
Activity 會被銷燬 onPause,onStop,onDestroy均會被呼叫,首先onSaveInstanceState來儲存當前Activity的狀態然後呼叫onstop-onDestroy-onCreate(有可能是空的)-onRestoreInstanceState(只要走這個方法那就是有資料的,可以進行資料恢復)可以恢復TextView的資料,listView 的訪問位置等等

設定旋轉螢幕不重新走生命週期可以在清單檔案的activity中設定 androdi:configChanges=“orientation (螢幕懸轉)| locale(本地位置發生改變)keyboardHidden(掉出了鍵盤)|screenLayout(屏幕布局發生了改變呼叫了另一個顯示裝置)|fontScale(換了一個新的字號)|ScreenSize(螢幕的尺寸資訊)|smallestScreenSize(物理螢幕發生改變)”

當橫豎屏切換的時候一般情況下 Activity會被銷燬然後重新建立 也可以阻止

Activity 的四大啟動模式

1.standard 預設模式,標準模式,不管任務棧中是否有這個例項的存在 都是新建一個例項出來 A 呼叫B ,會把B的例項建立在A 所在的任務棧中 ABCD 再次啟動就是ABCDD
2.singleTop 棧頂模式 ABCD 再次啟動D 還是ABCD
3.singleTask 棧內複用模式 系統會回撥onNewIntent 清除上面的棧
4.singleInstance 單例項模式 加強版的singleTask

fragment 的生命週期

1.onAttach() 關聯 Fragment和Activity建立關聯的時候呼叫,被附加到Activity中去。

2.onCreate() 建立 系統會在建立Fragment時呼叫此方法。可以初始化一段資原始檔等等。

3.onCreateView() 建立檢視 系統會在Fragment首次繪製其使用者介面時呼叫此方法。 要想為Fragment繪製 UI,從該方法中返回的 View 必須是Fragment佈局的根檢視。如果Fragment未提供 UI,您可以返回 null。

4.onViewCreated() 在Fragment被繪製後,呼叫此方法,可以初始化控制元件資源。

5.onActivityCreated() 當onCreate(),onCreateView(),onViewCreated()方法執行完後呼叫,也就是Activity被渲染繪製出來後。

6.onPause() 系統將此方法作為使用者離開Fragment的第一個訊號(但並不總是意味著此Fragment會被銷燬)進行呼叫。 通常可以在此方法內確認在當前使用者會話結束後仍然有效的任何更改(因為使用者可能不會返回)。

7.onDestroyView() Fragment中的佈局被移除時呼叫。

8.onDetach() Fragment和Activity解除關聯的時候呼叫。 但需要注一點是:除了onCreateView,其他的所有方法如果你重寫了,必須呼叫父類對於該方法的實現。

怎麼使用 分為兩種 一種是 靜態用法 一種是動態用法

靜態用法:1.繼承Fragment,重寫oncreateView 決定Fragment 的佈局
2.在Activity 中宣告次Fragment,就當普通的View 檢視是一樣的
動態用法:1.獲取到FragmentManager,在Activity中可以通過getFragmentManager 得到,
2.開啟一個事務,通過呼叫benginTransaction 方法開啟。
3.向容器內加入Fragment,一般使用replace 方法實現,需要傳入容器的id 和Fragment的例項
4.提交事務,呼叫commit方法提交

fragment啟動的生命週期
01-09 1:05:54.608 11678-11678/I/TAG: onAttach
01-09 1:05:54.608 11678-11678/I/TAG: onCreate
01-09 1:05:54.608 11678-11678/I/TAG: onCreateView
01-09 1:05:54.617 11678-11678/I/TAG: onViewCreated
01-09 1:05:54.618 11678-11678/I/TAG: onActivityCreated
01-09 1:05:54.619 11678-11678/I/TAG: onStart
01-09 1:05:54.619 11678-11678/I/TAG: onResume

Fragment豎屏旋轉到橫屏(橫屏旋轉回豎屏也是執行同樣的生命週期)
01-09 1:05:44.243 11678-11678/I/TAG: onPause
01-09 1:05:44.260 11678-11678/I/TAG: onStop
01-09 1:05:44.266 11678-11678/I/TAG: onDestroyView
01-09 1:05:44.267 11678-11678/I/TAG: onDestroy
01-09 1:05:44.267 11678-11678/I/TAG: onDetach
01-09 1:05:44.325 11678-11678/I/TAG: onAttach
01-09 1:05:44.326 11678-11678/I/TAG: onCreate
01-09 1:05:44.326 11678-11678/I/TAG: onCreateView
01-09 1:05:44.328 11678-11678/I/TAG: onViewCreated
01-09 1:05:44.330 11678-11678/I/TAG: onActivityCreated
01-09 1:05:44.330 11678-11678/I/TAG: onStart
01-09 1:05:44.330 11678-11678/I/TAG: onResume

Fragment退出
01-09 1:15:09.033 11678-11678/I/TAG: onPause
01-09 1:15:09.721 11678-11678/I/TAG: onStop
01-09 1:15:09.721 11678-11678/I/TAG: onDestroyView
01-09 1:15:09.721 11678-11678/I/TAG: onDestroy
01-09 1:15:09.721 11678-11678/I/TAG: onDetach

日常橫豎屏切換問題及解決方案
橫豎屏切換,導致Activity會重新啟動(生命週期流程:onPause()、onStop()、onDestroy()、onCreate()、onStart()、onResume())
1、Dialog
Dialog導致記憶體溢位、WindowTokenException等等
解決方案:DialogFragment替換Dialog.
2、Activity
Activity重建導致資料問題
1、Activity執行生命週期,先onPuase() —> onStop() —> onDestroy() —> onCreate() —> onStart() —> onResume()
2、如果在這些生命週期中,操作了某些資料,比如在onCreate中新增一條資訊“Name”,當橫豎屏切換時,又執行了onCreate()這就導致資訊“Name”被重複新增的,在資料集中重複出現,進而導致了資料的錯亂現象。
解決方案:
1、設定Activity橫豎屏時不執行生命週期的方法:
2、或則:在Activity銷燬時進行資料的及時的銷燬處理。
3、Fragment
1、Fragment重建,系統將會呼叫 無參構造方法進行重建。
解決方案:
1、引數資料,通過Bundle傳遞;不要建立其他有參的構造方法
2、預設保留一個公共的無參的構造方法(必須是公共的、無參的。PS:個人有次為了所謂的增強Fragment的封裝性,只想對外部丟擲newInstance()建立物件的方法,避免使用者呼叫無參的構造方法出現忘記傳值的問題,私自將 public SettingFragment 改為:private SettingFragment;由此導致Fragment的重建立時(例如:橫豎屏切換),導致無法初始化Fragment而終止執行,查其原因:系統在橫豎屏切換時進行例項化Fragment物件時,呼叫的是無參的構造方法,而如果設定為私有的則會導致系統呼叫無參構造方法失敗,進而導致例項化失敗)。