當前位置:首頁 » 安卓系統 » android銷毀fragment

android銷毀fragment

發布時間: 2023-02-06 09:31:36

Ⅰ Android——Fragment

Fragment必須總是被嵌入到一個activity之中,並且fragment的生命周期直接接受其宿主activity的生命周期的影響。你可以認為fragment是activity的一個模塊零件,它有自己的生命周期,接收它自己的輸入的事件,並且可以在activity運行時添加或者刪除。

應該將每一個fragment設計為模塊化和可復用化的activity組件。也就是說,你可以在多個activity中引用同一個fragment,因為fragment定義了它自己的布局,並且使用它本身生命周期回調的行為。

Fragment比Activity多了幾個額外的生命周期回調方法:

管理fragment生命周期與管理activity生命周期很相像,像activity一樣,fragment也有三種狀態:
1、Resumed:
fragment在運行中的activity中可見。

2、Paused:
另一個activity處於前台且得到焦點,但是這個fragment所在的activtiy仍然可見(前台activity部分透明,或者沒有覆蓋全屏)。

3、Stopped:
fragment不可見。要麼宿主activity已經停止,要麼fragment已經從activity上移除,但已被添加到後台棧中。一個停止的fragment仍然活著(所有的狀態和成員信息仍然由系統保留著)。但是,它對於用戶來講已經不再可見,並且如果activity被殺掉,它也將被殺掉。

如果activity的進程被殺掉了,在activity被重新創建時,你恢復fragment狀態。可以執行fragment的onSaveIntanceState()來保存狀態(注意:fragment是在onCreate(),onCreateView()或者onActivityCreate()中進行恢復)。

在生命周期方面,activity和fragment之間一個很重要的不同就是在各自的後台棧中是如何存儲的。當activity停止時,默認情況下activity被安置在由系統管理的activity後台棧中;fragment僅當在一個事務被移除時,通過顯式調用addToBackStack()請求保存的實例,該fragment才被置於由宿主activity管理的後台棧。

類似與Android系統為Activity維護一個任務棧,我們也可以通過Activity維護一個回退棧來保存每次Fragment事務發生的變化。

如果你將Fragment任務添加到回退棧,當用戶點擊後退按鈕時,將看到上一次的保存的Fragment。一旦Fragment完全從後退棧中彈出,用戶再次點擊後退鍵,則退出當前Activity。

通過Arguments創建Fragment,不建議通過為Fragment添加帶參數的構造函數

1、FragmentPagerAdapter:對於不再需要的fragment,選擇調用detach方法,僅銷毀視圖,並不會銷毀fragment實例。

2、FragmentStatePagerAdapter:會銷毀不再需要的fragment,當當前事務提交以後,會徹底的將fragment從當前Activity的FragmentManager中移除。

3、懶載入,核心方法是 setUserVisibleHint()

原因1:橫豎屏切換,造成Fragment重新實例化。
原因2:按下Home鍵,Activity處於後台,由於內存不足被銷毀,重新喚醒時Fragment重新實例化。

註:出現的原因是在 API24 之前的 v4包 的源碼問題,
解決方案:通過檢查onCreate的參數Bundle savedInstanceState就可以判斷,當前是否發生Activity的重新創建:

默認的savedInstanceState會存儲一些數據,只有在savedInstanceState==null時,才進行創建Fragment實例:

Ⅱ Android Fragment怎麼強制銷毀

具體方法如下:
一,可以銷毀的。創建fragment時,需要配置adapter,adapter繼承FragmentStatePagerAdapter 在此類中有重寫destroyItem,可以控制要銷毀哪些fragment了。
二,如果用的是tabhost + viewpager ,viewpager 默認就緩存了顯示頁的一前一後。就算是setOffscreenPageLimit(0)設置成0的話即是懶載入,但是默認的support-v4包會把默認值改為1的,也就是至少默認會載入下一頁,要想完全不載入,只有修改support-v4的源碼,然後重新打jar包調用了。

Ⅲ Android的Fragment知識點

frgment被創建的時候,相關的生命周期,
onAttach(), onCreate(), onCreateView(), onActivityCreated();
fragment對用戶可見的時候,相關的生命周期,
onStrat(), onResume(),
fragment進入「後台模式」的時候,相關的生命周期,
onPause(), onStop(),
fragment被銷毀的時候,相關的生命周期,
onPause(), onStop(), onDestroyView(), onDestroy(), onDetach()
可用onCreate()、onCreateView()、onActivityCreated()方法Bundle對象保存一個fragment的對象

onAttach():Fragment和Activity相關聯時調用,可以通過該方法獲取Activity引用,還可以通過getArguments()獲取參數。
onCreate():Fragment創建時被調用。
onCreateView():創建Fragment的布局。
onActivityCreated():當Activity完成onCreate時調用。
onStart():當Fragment可見時。
onResume():當Fragment可見,且可交互時調用。
onPause():當Fragment不可交互,但可見時。
onStop():當Fragment不可見時。
onDestroyView():當Fragment的UI從視圖結構中移除時調用。
onDestroy():銷毀Fragment時
onDetach():當Fragment和Activity解除關聯時調用。

Ⅳ Android-ViewModel原理解析

在這四個方法中,其實唯一的區別就是要不要傳Factory,當沒有傳自定義的Factory的時候,則會傳入默認的Factory,我們看ViewModelProvider構造器的源碼和部分of方法的源碼:

在ViewModelProvider中需要傳入一個VieModelStore對象,這個對象是由ViewModelStoreOwner來提供的,而在Activity或者Fragment中,是由Activity和Fragment來提供的,因為ViewModelStoreOwner是一個介面,而AppCompatActivity的祖父ComponentActivity和Fragment均實現了ViewModelStoreOwner介面。

但是ViewModelProviders在新的lifecycle-extensions庫中,已經是屬於被棄用的。新版的API直接使用ViewModelProvider,而不是ViewModelProviders。
比如:

可以如下的方式在baseActivity中添加,由子類Activity調用:

創建ViewModel對象,首先就需要先初始化一個ViewModelProvider對象

可以看出,ViewModelProvider構造函數其實最終都是需要兩個參數,一個是ViewModelStoreOwner對象,一個是Factory。而ViewModelStoreOwner其實就是用來獲取一個ViewModelStore對象來保存ViewModel對象的。而Factory就是用來創建ViewModel對象的。

這個介面的主要實現的作用就是返回一個ViewModelStore對象。在Android中,Activity和Fragment都會實現該介面,並且實現getViewModelStore()方法。
比如Activity就是在FragmentActivity的父類ComponentActivity中實現了ViewModelStoreOwner介面

Fragment的ViewModelStore其實是由FragmentManager進行管理獲取

每個FragmentActivity都會有一個自己的FragmentManager對象,所以每個FragmentManagerViewModel對象,管理的是一個FragmentActivity中的所有的Fragment對應的ViewModel。具體看FragmentManagerViewModel的getViewModelStore方法

從這里可以看出,每個Fragment都會有自己的ViewModelStore對象,而ViewModelStore對象,是根據每個Fragment的唯一標識進行創建的。

ViewModelStore類對象,是每個Activity或者Fragment都有一個,目的是用於保存該頁面的ViewModel對象,方便ViewModel的管理

從ViewModelProvider的get方法中,可以看出,get方法傳入的是一個ViewModel.class的Class類型,然後通過這個類型,得到ViewModel的規范名稱。將ViewModel對象緩存在ViewModelStore中的HashMap中。而ViewModel的創建,其實是通過ViewModelProvider.Factory來實現的

ViewModelProviders的of方法,用於返回一個ViewModelProvider對象

從這里我們可以看到,如果傳入的Activity或者Fragment有方法實現,而factory為null的時候,則會通過創建對應的Factory,而如果沒有的實現,那麼就會調用NewInstanceFactory來創建對應的Factory,而NewInstanceFactory其實就是創建AndroidViewModelFactory對象。
最終ViewModel對象,其實就是通過AndroidViewModelFactory的create的方法實現來創建。一般就是通過Class.newInstance或者Class.getConstructor來創建對象。

而ViewModelProvider的第一個參數,其實最終傳入的是ViewModelStore對象,這個對象內部是通過一個HashMap來保存ViewModel對象
而新版的源碼,ViewModelStore對象是通過Fragment和FragmentActivity對象的getViewModelStore方法來獲取,而原先的HolderFragment的功能都移植到了Fragment中

HolderFragment通過設置setRetainInstance(true),使得自身能夠不受到屏幕旋轉等configuration
changes影響而存活,直到依附的Activity正常結束。
因為HolderFragment的生命周期,ViewModelStore對象保存在HolderFragment中,而ViewModel又存儲在ViewModelStore中,這就是為什麼我們說ViewModel類能夠讓數據在屏幕旋轉等配置信息改變導致UI重建的情況下不被銷毀。

ViewModelProvider的get方法:

在ViewModel中,有兩種Factory,Factory是的類型是由ViewModelProvider在初始化的時候創建的,所以是由ViewModelProvider決定Factory的類型。在ViewModelProvider中,有兩種Factory,一種是默認的Factory,默認的Factory是通過在ComponentActivity或者Fragment中實現介面,然後在()方法中初始化一個SavedStateViewModelFactory對象;另一種Factory則是NewInstanceFactory,這種是通過NewInstanceFactory.getInstance()的單例方式獲取。

其實就是通過ViewModel的Class對象,然後通過反射創建ViewModel對象,然後保存到ViewModelStore中的Map集合中
從ViewModelProvider的get方法可以看出,在ViewModelProvider的get方法中會根據Factory的類型,進行不同方法的調用。SavedStateViewModelFactory是實現了ViewModelProvider.KeyedFactory介面的,所以在創建ViewModel的時候,調用的是SavedStateViewModelFactory的create方法。

AndroidViewModel和ViewModel的構造器參數Class

ViewModel保存和恢復數據
ComponentActivity和Fragment都將數據的保存和恢復邏輯轉發給了SavedStateRegistryController。在在onCreate方法里通過調用performRestore來恢復數據,在onSaveInstanceState方法里通過調用performSave來保存數據。而SavedStateRegistryController中的SavedStateRegistry對象,就是實際進行數據的保存和恢復的,在SavedStateRegistry通過唯一的key獲取到一個SavedStateProvider,而SavedStateProvider其實就是返回需要保存的數據,將對應的需要緩存的數據一一返回,然後保存在系統緩存時的回調到onSaveInstanceState的方法參數Bundle中進行保存。
SavedStateRegistry.performSave()
該方法是由ComponentActivity的onSaveInstanceState方法觸發調用SavedStateRegistryController的performSave,進而調用的

在SavedStateRegistry恢復數據的時候,會把恢復後的數據都交給SavedStateHandle。希望保留的數據,可以通過兩種方式向mRegular保存數據。

在ComponentActivity恢復數據的時候,會通過SavedStateRegistryController.performSave在Activity的onSaveInstanceState方法中進行數據的保存,然後在ComponentActivity的onCreate方法中,通過調用SavedStateRegistryController.performRestore方法進行數據的恢復,這些恢復的數據都會保存在SavedStateHandleController對象中的SavedStateHandle屬性中,然後在Activity重新創建的時候,會通過反射創建對應的ViewModel對象的時候,將SavedStateHandleController中的SavedStateHandle賦值給對應的ViewModel進行數據恢復。

這塊的源碼分析可以參考:
從源碼看 Jetpack(7)-SavedStateHandle源碼詳解

這里其實就是直接使用Class的newInstance直接創建對象。Activity和Fragment一般都是使用SavedStateViewModelFactory創建ViewModel對象。

ViewModel的銷毀,要分為Activity和Fragment兩部分。
首先看下ViewModel在銷毀的時候做的事情

而ViewModel的clear()方法的調用,是在ViewModelStore中

Activity的銷毀,是通過Lifecycle監聽生命周期回調,當生命周期執行到onDestroy的時候,調用ViewModelStore的clear()方法進行ViewModel的銷毀。
看ComponentActivity中構造器中的實現:

Fragment的生命周期管理,如下:

Fragment的生命周期,首先會依次增大,然後在從onResume變成onPause的時候,就開始狀態碼減小。即先升再降的一個狀態變化。在當前狀態碼變成CREATED的時候,就會執行onDestroy。即調用

FragmentStateManager.destroy

在這里就會調用nonConfig.clearNonConfigState方法,nonConfig其實就是FragmentManagerViewModel對象。
FragmentManagerViewModel.clearNonConfigState

按照上面的邏輯,在Activity重建時會執行destory生命周期事件,那麼為什麼ViewModel沒有銷毀呢?
其實就是在屏幕旋轉的時候,AMS通過Binder回調Activity的()方法,這個時候就會進行數據的保存,保存到一個NonConfigurationInstances對象;而在屏幕翻轉結束之後,會再一次調用ViewModelProvider的構造函數,此時就會調用owner.getViewModelStore(),接著就會調用(),這里就會通過Activity中的NonConfigurationInstances對象取出保存的ViewModelStore對象。
所以數據保存就是通過()方法保存在NonConfigurationInstances對象,而再一次使用取出ViewModel的數據的時候,就是從nc對象中取出ViewModelStore對象,而ViewModelStore對象保存有ViewModel集合
通過對ComponentActivity的getViewModelStore()方法進行分析。可以找到這個問題的答案。

當mViewModelStore為null的時候,會從NonConfigurationInstances中獲取ViewModelStore對象。
其實在ComponentActivity和Activity中都會有一個NonConfigurationInstances類,而Activity中的NonConfigurationInstances類結構如下:

這里的Object activity其實就是保存的ComponentActivity中的NonConfigurationInstances類對象,看Activity的下面的方法:

activity這個Object對象,其實是通過()方法返回值賦值,而()方法的實現是在ComponentActivity中。
看ComponentActivity中的下面方法:

因為這里會在ComponentActivity中的NonConfigurationInstances類對象中保存ViewModelStore對象,所以這也是Activity重建時不會銷毀ViewModel的原因。

()方法除了被Activity的()調用以外,還會被LocalActivityManager的()方法調用

在分析ViewModel的銷毀過程時,我們看到Activity與Fragment存儲VieModel是分離的,那麼同一個Activity下的Fragment是如何共享ViewModel的呢?
其實共享的是Activity的ViewModel。

而具體的實現邏輯,其實就是在FragmentViewModelLazy.kt中的:

在Fragment中可以直接調用,這是一個Fragment的擴展函數,通過實現requireActivity().viewModelStore,獲取到了Activity的ViewModelStore對象後,這樣就可以實現了Fragment共用Activity的ViewModel,從而實現了Fragment之間共享ViewModel。
Fragment之間共享ViewModel,需要引入

Ⅳ Android Fragment怎麼強制銷毀

android fragment的生命周期是隨著綁定的activity的,所以要強制銷毀的話,可以把ativity殺死。如果不需要fragment你可以先hide隱藏掉即可。

Ⅵ Android Fragment怎麼強制銷毀

Fragment是activity的碎片 你可以吧activity finish()掉它就會銷毀了,你可以看一下Fragment的生命周期。

Ⅶ Android Fragment怎麼強制銷毀

要銷毀線程,你要設置break條件去跳出循環的,不然無法銷毀。除非kill整個進程。你寫循環的時候就寫:
boolean volatile isRunning = true;
while (isRunning) {}

要銷毀的時候設置isRunning = false;

熱點內容
星途買哪個配置啊 發布:2025-07-15 11:14:35 瀏覽:521
蘋果手機刪除緩存文件 發布:2025-07-15 11:08:01 瀏覽:957
安卓手機桌面變大軟體怎麼恢復 發布:2025-07-15 11:07:47 瀏覽:605
酒店密碼門禁是什麼牌子 發布:2025-07-15 11:06:56 瀏覽:968
下載winrar解壓縮 發布:2025-07-15 10:59:36 瀏覽:314
光遇無翼號怎麼弄安卓 發布:2025-07-15 10:45:59 瀏覽:365
什麼是法人賬號密碼 發布:2025-07-15 10:34:59 瀏覽:876
編程題抽獎 發布:2025-07-15 10:34:00 瀏覽:629
linux手動編譯的內核怎麼刪 發布:2025-07-15 10:31:56 瀏覽:96
存儲行業發展趨勢 發布:2025-07-15 10:25:22 瀏覽:243