棧:存放基礎(chǔ)數(shù)據(jù)類型跟局部變量會(huì)自動(dòng)回收
創(chuàng)新互聯(lián)主營寧縣網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP軟件開發(fā),寧縣h5微信平臺(tái)小程序開發(fā)搭建,寧縣網(wǎng)站營銷推廣歡迎寧縣等地區(qū)企業(yè)咨詢
堆:存放new 對象,GC會(huì)回收這里面的對象
常量池:存放字符串常量和基本類型常量(public static final)一開始就已經(jīng)定義了
區(qū)別: 這里我們主要關(guān)心棧,堆和常量池,對于棧和常量池中的對象可以共享,對于堆中的對象不可以共享。棧中的數(shù)據(jù)大小和生命周期是可以確定的,當(dāng)沒有引用指向數(shù)據(jù)時(shí),這個(gè)數(shù)據(jù)就會(huì)消失。堆中的對象的由垃圾回收器負(fù)責(zé)回收,因此大小和生命周期不需要確定,具有很大的靈活性。
對于字符串:其對象的引用都是存儲(chǔ)在棧中的,如果是編譯期已經(jīng)創(chuàng)建好(直接用雙引號定義的)的就存儲(chǔ)在常量池中,如果是運(yùn)行期(new出來的)才能確定的就存儲(chǔ)在堆中。對于equals相等的字符串,在常量池中永遠(yuǎn)只有一份,在堆中有多份。
amdroid將Activity放入全局棧如下:
import java.util.Stack;
import android.app.Activity;
public class ScreenManager {
private static Stack activityStack;
private static ScreenManager instance;
private ScreenManager(){
}
public static ScreenManager getScreenManager(){
if(instance==null){
Activity是Android程序的表現(xiàn)層。程序的每一個(gè)顯示屏幕就是一個(gè)Activity。正在運(yùn)行的Activity處在棧的最頂端,它是運(yùn)行狀態(tài)的。
目錄
activity的簡單介紹就不寫了,作為最常用的四大組件之一,肯定都很熟悉其基本用法了。
首先,是都很熟悉的一張圖,即官方介紹的Activity生命周期圖.
情景:打開某個(gè)應(yīng)用的的FirstActivity調(diào)用方法如下:
由于之前已經(jīng)很熟悉了,這里就簡單貼一些圖。
按下返回鍵:
重新打開并按下home鍵:
再重新打開:
在其中打開一個(gè)DialogActivity(SecondActivity)
按下返回:
修改SecondAcitvity為普通Activity,依舊是上述操作:
這里強(qiáng)調(diào)一下 onSaveInstanceState(Bundle outState) 方法的調(diào)用時(shí)機(jī):
當(dāng)Activity有可能被系統(tǒng)殺掉時(shí)調(diào)用,注意,一定是被系統(tǒng)殺掉,自己調(diào)用finish是不行的。
測試如下:FirstActivity啟動(dòng)SecondActivity:
一個(gè)App會(huì)包含很多個(gè)Activity,多個(gè)Activity之間通過intent進(jìn)行跳轉(zhuǎn),那么原始的Activity就是使用棧這個(gè)數(shù)據(jù)結(jié)構(gòu)來保存的。
Task
A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened.
即若干個(gè)Activity的集合的棧表示一個(gè)Task。
當(dāng)App啟動(dòng)時(shí)如果不存在當(dāng)前App的任務(wù)棧就會(huì)自動(dòng)創(chuàng)建一個(gè),默認(rèn)情況下一個(gè)App中的所有Activity都是放在一個(gè)Task中的,但是如果指定了特殊的啟動(dòng)模式,那么就會(huì)出現(xiàn)同一個(gè)App的Activity出現(xiàn)在不同的任務(wù)棧中的情況,即會(huì)有任務(wù)棧中包含來自于不同App的Activity。
標(biāo)準(zhǔn)模式,在不指定啟動(dòng)模式的情況下都是以此種方式啟動(dòng)的。每次啟動(dòng)都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例,覆蓋在原有的Activity上,原有的Activity入棧。
測試如下:在FirstActivity中啟動(dòng)FirstActivity:
當(dāng)只有一個(gè)FirstActivity時(shí)堆棧情況:
此種模式下,Activity在啟動(dòng)時(shí)會(huì)進(jìn)行判斷,如果當(dāng)前的App的棧頂?shù)腁ctivity即正在活動(dòng)的Activity就是將要啟動(dòng)的Activity,那么就不會(huì)創(chuàng)建新的實(shí)例,直接使用棧頂?shù)膶?shí)例。
測試,設(shè)置FirstActivity為此啟動(dòng)模式,多次點(diǎn)擊FirstActivity中的啟動(dòng)FirstActivity的按鈕查看堆棧情況:
(其實(shí)點(diǎn)擊按鈕沒有啟動(dòng)新Activity的動(dòng)畫就可以看出并沒有啟動(dòng)新Activity)
大意就是:
對于使用singleTop啟動(dòng)或Intent.FLAG_ACTIVITY_SINGLE_TOP啟動(dòng)的Activity,當(dāng)該Activity被重復(fù)啟動(dòng)(注意一定是re-launched,第一次啟動(dòng)時(shí)不會(huì)調(diào)用)時(shí)就會(huì)調(diào)用此方法。
且調(diào)用此方法之前會(huì)先暫停Activity也就是先調(diào)用onPause方法。
而且,即使是在新的調(diào)用產(chǎn)生后此方法被調(diào)用,但是通過getIntent方法獲取到的依舊是以前的Intent,可以通過setIntent方法設(shè)置新的Intent。
方法參數(shù)就是新傳遞的Intent.
1.如果是同一個(gè)App中啟動(dòng)某個(gè)設(shè)置了此模式的Activity的話,如果棧中已經(jīng)存在該Activity的實(shí)例,那么就會(huì)將該Activity上面的Activity清空,并將此實(shí)例放在棧頂。
測試:SecondActivity啟動(dòng)模式設(shè)為singleTask,啟動(dòng)三個(gè)Activity:
這個(gè)模式就很好記,以此模式啟動(dòng)的Activity會(huì)存放在一個(gè)單獨(dú)的任務(wù)棧中,且只會(huì)有一個(gè)實(shí)例。
測試:SecondActivity啟動(dòng)模式設(shè)為singleInstance
結(jié)果:
顯然,啟動(dòng)了兩次ThirdActivity任務(wù)棧中就有兩個(gè)實(shí)例,而SecondActivity在另外一個(gè)任務(wù)棧中,且只有一個(gè)。
在使用Intent啟動(dòng)一個(gè)Activity時(shí)可以設(shè)置啟動(dòng)該Activity的啟動(dòng)模式:
這個(gè)屬性有很多,大致列出幾個(gè):
每個(gè)啟動(dòng)的Activity都在一個(gè)新的任務(wù)棧中
singleTop
singleTask
用此種方式啟動(dòng)的Activity,在它啟動(dòng)了其他Activity后,會(huì)自動(dòng)finish.
官方文檔介紹如下:
這樣看來的話,通俗易懂的講,就是給每一個(gè)任務(wù)棧起個(gè)名,給每個(gè)Activity也起個(gè)名,在Activity以singleTask模式啟動(dòng)時(shí),就檢查有沒有跟此Activity的名相同的任務(wù)棧,有的話就將其加入其中。沒有的話就按照這個(gè)Activity的名創(chuàng)建一個(gè)任務(wù)棧。
測試:在App1中設(shè)置SecondActivity的taskAffinity為“gsq.test”,App2中的ActivityX的taskAffinity也設(shè)為“gsq.test”
任務(wù)棧信息如下:
結(jié)果很顯然了。
測試:在上述基礎(chǔ)上,在ActivityX中進(jìn)行跳轉(zhuǎn)到ActivityY,ActivityY不指定啟動(dòng)模式和taskAffinity。結(jié)果如下:
這樣就沒問題了,ActivityY在一個(gè)新的任務(wù)棧中,名稱為包名。
這時(shí)從ActivityY跳轉(zhuǎn)到SecondActivity,那應(yīng)該是gsq.test任務(wù)棧只有SecondActivity,ActivityX已經(jīng)沒有了。因?yàn)槠鋯?dòng)模式是singleTask,在啟動(dòng)它時(shí)發(fā)現(xiàn)已經(jīng)有一個(gè)實(shí)例存在,就把它所在的任務(wù)棧上面的Activity都清空了并將其置于棧頂。
還有一點(diǎn)需要提一下,在上面,F(xiàn)irstActivity是App1的lunch Activity,但是由于SecondActivity并沒有指定MAIN和LAUNCHER過濾器,故在FirstActivity跳轉(zhuǎn)到SecondActivity時(shí),按下home鍵,再點(diǎn)開App1,回到的是FirstActivity。
大致就先寫這么多吧,好像有點(diǎn)長,廢話有點(diǎn)多,估計(jì)也有錯(cuò)別字,不要太在意~~~
任務(wù)棧分為前臺(tái)的任務(wù)棧,當(dāng)前activity活動(dòng)所在的棧稱為前臺(tái)任務(wù)棧。
任務(wù)是指在執(zhí)行特定作業(yè)(任務(wù) task)時(shí)與用戶交互的activity。這些Activity按照各自打開的順序 排列在堆棧(返回棧)中。設(shè)備的屏幕 桌面的圖標(biāo)(launcher)是多數(shù)據(jù)任務(wù)的的起點(diǎn)。當(dāng)用戶觸摸應(yīng)用啟動(dòng)器中的圖標(biāo)時(shí),該用戶的任務(wù)將出現(xiàn)在前臺(tái)。如果應(yīng)用不存在任務(wù)(應(yīng)用未曾使用),則會(huì)創(chuàng)建一個(gè)新的任務(wù),并且該應(yīng)用的"主Activity將作為堆棧中的根Activity打開"。
當(dāng)Activity啟動(dòng)另一個(gè)Activity時(shí),該新Activity會(huì)被推送到堆棧的頂部,如果當(dāng)前app只有一個(gè)棧 且app處于前臺(tái),那么這個(gè)棧頂?shù)腁ctivity用戶應(yīng)該是可見的,而啟動(dòng)棧頂這個(gè)Activity(啟動(dòng)者)仍然保留在堆棧中,但是是處于停止?fàn)顟B(tài)。Activity停止時(shí)系統(tǒng)會(huì)保留其用戶信息 在Activity onSaveInstanceSate、 onRestoreInstanceState(Bundle savedInstanceState) 方法 具體可以查看這兩個(gè)方法。當(dāng)用戶按"返回"按鈕時(shí),當(dāng)前Activity(所謂當(dāng)前Activity一定是用戶可以看到的在棧頂?shù)?會(huì)從堆棧頂部彈出(Activity被銷毀 走onDestory方法)這里說銷毀也不太嚴(yán)格 因?yàn)檎G闆r下會(huì)被銷毀 在不存在內(nèi)泄漏導(dǎo)致Activity回收不掉的情況。棧頂?shù)腁ctivity被銷毀 它下面的Activity就會(huì)恢復(fù)執(zhí)行(下面這個(gè)Activity露頭你可以看到它了)。堆棧中的Activity永遠(yuǎn)不會(huì)重新排序,我們操作app的功能時(shí) 僅僅是 進(jìn)入頁面(壓棧)退出頁面(彈棧),因此返回棧(彈棧)以 "后進(jìn)先出"的對象結(jié)構(gòu)運(yùn)行。
任務(wù)是一個(gè)有機(jī)整體,當(dāng)用戶開始新任務(wù)或通過點(diǎn)擊"home鍵" 這個(gè)時(shí)候應(yīng)用會(huì)切換到“后臺(tái)”,在后臺(tái)時(shí)該任務(wù)中的所有Activity全部停止,但是任務(wù)的返回棧仍舊不變,也就是說,當(dāng)另一個(gè)任務(wù)發(fā)生時(shí),該任務(wù)僅是失敗焦點(diǎn)而已
如何更通過api查看當(dāng)前應(yīng)用中的任務(wù)
發(fā)現(xiàn)當(dāng)前只有一個(gè)任務(wù)
同時(shí)通過這個(gè)任務(wù)我們可以查看當(dāng)前棧頂?shù)腶ctivity如下圖
用戶通過系統(tǒng)返回按鈕導(dǎo)航回去的一組頁面,在開發(fā)中被稱為返回棧 (back stack)。多返回棧即一堆 "返回棧",對多返回棧的支持是在 Navigation 2.4.0-alpha01 和 Fragment 1.4.0-alpha01 中開始的。本文將為您展開多返回棧的技術(shù)詳解。
無論您在使用 Android 全新的 手勢導(dǎo)航 還是傳統(tǒng)的導(dǎo)航欄,用戶的 "返回" 操作是 Android 用戶體驗(yàn)中關(guān)鍵的一環(huán),把握好返回功能的設(shè)計(jì)可以使應(yīng)用更加貼近整個(gè)生態(tài)系統(tǒng)。
在最簡單的應(yīng)用場景中,系統(tǒng)返回按鈕僅僅 finish 您的 Activity。在過去您可能需要覆寫 Activity 的 onBackPressed() 方法來自定義返回操作,而在 2021 年您無需再這樣操作。我們已經(jīng)在 OnBackPressedDispatcher 中提供了 針對自定義返回導(dǎo)航的 API。實(shí)際上這與 FragmentManager 和 NavController 中 已經(jīng) 添加的 API 相同。
這意味著當(dāng)您使用 Fragments 或 Navigation 時(shí),它們會(huì)通過 OnBackPressedDispatcher 來確保您調(diào)用了它們返回棧的 API,系統(tǒng)的返回按鈕會(huì)將您推入返回棧的頁面逐層返回。
多返回棧不會(huì)改變這個(gè)基本邏輯。系統(tǒng)的返回按鈕仍然是一個(gè)單向指令 —— "返回"。這對多返回棧 API 的實(shí)現(xiàn)機(jī)制有深遠(yuǎn)影響。
在 surface 層級,對于 多返回棧的支持 貌似很直接,但其實(shí)需要額外解釋一下 "Fragment 返回棧" 到底是什么。FragmentManager 的返回棧其實(shí)包含的不是 Fragment,而是由 Fragment 事務(wù)組成的。更準(zhǔn)確地說,是由那些調(diào)用了 addToBackStack(String name) API 的事務(wù)組成的。
這就意味著當(dāng)您調(diào)用 commit() 提交了一個(gè)調(diào)用過 addToBackStack() 方法的 Fragment 事務(wù)時(shí), FragmentManager 會(huì)執(zhí)行所有您在事務(wù)中所指定的操作 (比如 替換操作 ),從而將每個(gè) Fragment 轉(zhuǎn)換為預(yù)期的狀態(tài)。然后 FragmentManager 會(huì)將該事務(wù)作為它返回棧的一部分。
當(dāng)您調(diào)用 popBackStack() 方法時(shí) (無論是直接調(diào)用,還是通過系統(tǒng)返回鍵以 FragmentManager 內(nèi)部機(jī)制調(diào)用),F(xiàn)ragment 返回棧的最上層事務(wù)會(huì)從棧中彈出 -- 比如新添加的 Fragment 會(huì)被移除,隱藏的 Fragment 會(huì)顯示。這會(huì)使得 FragmentManager 恢復(fù)到最初提交 Fragment 事務(wù)之前的狀態(tài)。
也就是說 popBackStack() 變成了銷毀操作: 任何已添加的 Fragment 在事務(wù)被彈出的時(shí)候都會(huì)丟失它的狀態(tài)。換言之,您會(huì)失去視圖的狀態(tài),任何所保存的實(shí)例狀態(tài) (Saved Instance State),并且任何綁定到該 Fragment 的 ViewModel 實(shí)例都會(huì)被清除。這也是該 API 和新的 saveBackStack() 方法之間的主要區(qū)別。 saveBackStack() 可以實(shí)現(xiàn)彈出事務(wù)所實(shí)現(xiàn)的返回效果,此外它還可以確保視圖狀態(tài)、已保存的實(shí)例狀態(tài),以及 ViewModel 實(shí)例能夠在銷毀時(shí)被保存。這使得 restoreBackStack() API 后續(xù)可以通過已保存的狀態(tài)重建這些事務(wù)和它們的 Fragment,并且高效 "重現(xiàn)" 已保存的全部細(xì)節(jié)。太神奇了!
而實(shí)現(xiàn)這個(gè)目的必須要解決大量技術(shù)上的問題。
雖然 Fragment 總是會(huì)保存 Fragment 的視圖狀態(tài),但是 Fragment 的 onSaveInstanceState() 方法只有在 Activity 的 onSaveInstanceState() 被調(diào)用時(shí)才會(huì)被調(diào)用。為了能夠保證調(diào)用 saveBackStack() 時(shí) SavedInstanceState 會(huì)被保存,我們 還 需要在 Fragment 生命周期切換 的正確時(shí)機(jī)注入對 onSaveInstanceState() 的調(diào)用。我們不能調(diào)用得太早 (您的 Fragment 不應(yīng)該在 STARTED 狀態(tài)下保存狀態(tài)),也不能調(diào)用得太晚 (您需要在 Fragment 被銷毀之前保存狀態(tài))。
這樣的前提條件就開啟了需要 解決 FragmentManager 轉(zhuǎn)換到對應(yīng)狀態(tài)的問題,以此來保障有一個(gè)地方能夠?qū)?Fragment 轉(zhuǎn)換為所需狀態(tài),并且處理可重入行為和 Fragment 內(nèi)部的狀態(tài)轉(zhuǎn)換。
在 Fragment 的重構(gòu)工作進(jìn)行了 6 個(gè)月,進(jìn)行了 35 次修改時(shí),發(fā)現(xiàn) Postponed Fragment 功能已經(jīng)嚴(yán)重?fù)p壞,這一問題使得被推遲的事務(wù)處于一個(gè)中間狀態(tài) —— 既沒有被提交也并不是未被提交。之后的 65 個(gè)修改和 5 個(gè)月的時(shí)間里,我們幾乎重寫了 FragmentManager 管理狀態(tài)、延遲狀態(tài)切換和動(dòng)畫的內(nèi)部代碼,具體請參見我們之前的文章《全新的 Fragment: 使用新的狀態(tài)管理器》。
隨著技術(shù)問題的逐步解決,包括更加可靠和更易理解的 FragmentManager ,我們新增加了兩個(gè) API: saveBackStack() 和 restoreBackStack() 。
如果您不使用這些新增 API,則一切照舊: 單個(gè) FragmentManager 返回棧和之前的功能相同。現(xiàn)有的 addToBackStack() 保持不變 —— 您可以將 name 賦值為 null 或者任意 name 。然而,當(dāng)您使用多返回棧時(shí), name 的作用就非常重要了: 在您調(diào)用 saveBackStack() 和之后的 restoreBackStack() 方法時(shí),它將作為 Fragment 事務(wù)的唯一的 key。
舉個(gè)例子,會(huì)更容易理解。比如您已經(jīng)添加了一個(gè)初始的 Fragment 到 Activity,然后提交了兩個(gè)事務(wù),每個(gè)事務(wù)中包含一個(gè)單獨(dú)的 replace 操作:
也就是說我們的 FragmentManager 會(huì)變成這樣:
比如說我們希望將 profile 頁換出返回棧,然后切換到通知 Fragment。這就需要調(diào)用 saveBackStack() 并且緊跟一個(gè)新的事務(wù):
現(xiàn)在我們添加 ProfileFragment 的事務(wù)和添加 EditProfileFragment 的事務(wù)都保存在 "profile" 關(guān)鍵字下。這些 Fragment 已經(jīng)完全將狀態(tài)保存,并且 FragmentManager 會(huì)隨同事務(wù)狀態(tài)一起保持它們的狀態(tài)。很重要的一點(diǎn): 這些 Fragment 的實(shí)例并不在內(nèi)存中或者在 FragmentManager 中 —— 存在的僅僅只有狀態(tài) (以及任何以 ViewModel 實(shí)例形式存在的非配置狀態(tài))。
替換回來非常簡單: 我們可以在 "notifications" 事務(wù)中同樣調(diào)用 saveBackStack() 操作,然后調(diào)用 restoreBackStack() :
這兩個(gè)堆棧項(xiàng)高效地交換了位置:
維持一個(gè)單獨(dú)且活躍的返回棧并且將事務(wù)在其中交換,這保證了當(dāng)返回按鈕被點(diǎn)擊時(shí), FragmentManager 和系統(tǒng)的其他部分可以保持一致的響應(yīng)。實(shí)際上,整個(gè)邏輯并未改變,同之前一樣,仍然彈出 Fragment 返回棧的最后一個(gè)事務(wù)。
這些 API 都特意按照最小化設(shè)計(jì),盡管它們會(huì)產(chǎn)生潛在的影響。這使得開發(fā)者可以基于這些接口設(shè)計(jì)自己的結(jié)構(gòu),而無需通過任何非常規(guī)的方式保存 Fragment 的視圖狀態(tài)、已保存的實(shí)例狀態(tài)、非配置的狀態(tài)。
當(dāng)然了,如果您不希望在這些 API 之上構(gòu)建您的框架,那么可以使用我們所提供的框架進(jìn)行開發(fā)。
Navigation Component 最初 是作為通用運(yùn)行時(shí)組件進(jìn)行開發(fā)的,其中不涉及 View、Fragment、Composable 或者其他屏幕顯示相關(guān)類型及您可能會(huì)在 Activity 中實(shí)現(xiàn)的 "目的地界面"。然而,NavHost 接口 的實(shí)現(xiàn)中需要考慮這些內(nèi)容,通過它添加一個(gè)或者多個(gè) Navigator 實(shí)例時(shí),這些實(shí)例 確實(shí) 清楚如何與特定類型的目的地進(jìn)行交互。
這也就意味著與 Fragment 的交互邏輯全部封裝在了 navigation-fragment 開發(fā)庫和它其中的 FragmentNavigator 與 DialogFragmentNavigator 中。類似的,與 Composable 的交互邏輯被封裝在完全獨(dú)立的 navigation-compose 開發(fā)庫和它的 ComposeNavigator 中。這里的抽象設(shè)計(jì)意味著如果您希望僅僅通過 Composable 構(gòu)建您的應(yīng)用,那么當(dāng)您使用 Navigation Compose 時(shí)無需任何涉及到 Fragment 的依賴。
該級別的分離意味著 Navigation 中有兩個(gè)層次來實(shí)現(xiàn)多返回棧:
仍需特別注意那些 尚未 更新的 Navigator ,它們無法支持保存自身狀態(tài)。底層的 Navigator API 已經(jīng)整體重寫來支持狀態(tài)保存 (您需要覆寫新增的 navigate() 和 popBackStack() API 的重載方法,而不是覆寫之前的版本),即使 Navigator 并未更新, NavController 仍會(huì)保存 NavBackStackEntry 的狀態(tài) (在 Jetpack 世界中向后兼容是非常重要的)。
如果您僅僅在應(yīng)用中使用 Navigation,那么 Navigator 這個(gè)層面更多的是實(shí)現(xiàn)細(xì)節(jié),而不是您需要直接與之交互的內(nèi)容。可以這么說,我們已經(jīng)完成了將 FragmentNavigator 和 ComposeNavigator 遷移到新的 Navigator API 的工作,使其能夠正確地保存和恢復(fù)它們的狀態(tài),在這個(gè)層面上您無需再做任何額外工作。
如果您正在使用 NavigationUI,它是用于連接您的 NavController 到 Material 視圖組件的一系列專用助手,您會(huì)發(fā)現(xiàn)對于菜單項(xiàng)、 BottomNavigationView (現(xiàn)在叫 NavigationRailView ) 和 NavigationView ,多返回棧是 默認(rèn)啟用 的。這就意味著結(jié)合 navigation-fragment 和 navigation-ui 使用就可以。
NavigationUI API 是基于 Navigation 的其他公共 API 構(gòu)建的,確保您可以準(zhǔn)確地為自定義組件構(gòu)建您自己的版本。保證您可以構(gòu)建所需的自定義組件。啟用保存和恢復(fù)返回棧的 API 也不例外,在 Navigation XML 中通過 NavOptions 上的新 API,也就是 navOptions Kotlin DSL,以及 popBackStack() 的重載方法可以幫助您指定 pop 操作保存狀態(tài)或者指定 navigate 操作來恢復(fù)之前已保存的狀態(tài)。
比如,在 Compose 中,任何全局的導(dǎo)航模式 (無論是底部導(dǎo)航欄、導(dǎo)航邊欄、抽屜式導(dǎo)航欄或者任何您能想到的形式) 都可以使用我們在與 底部導(dǎo)航欄集成 所介紹的相同的技術(shù),并且結(jié)合 saveState 和 restoreState 屬性一起調(diào)用 navigate() :
對用戶來說,最令人沮喪的事情之一便是丟失之前的狀態(tài)。這也是為什么 Fragment 用一整頁來講解 保存與 Fragment 相關(guān)的狀態(tài),而且也是我非常樂于更新每個(gè)層級來支持多返回棧的原因之一:
如果您希望了解 更多使用該 API 的示例,請參考 NavigationAdvancedSample (它是最新更新的,且不包含任何用于支持多返回棧的 NavigationExtensions 代碼)。
對于 Navigation Compose 的示例,請參考 Tivi。
如果您遇到任何問題,請使用官方的問題追蹤頁面提交關(guān)于 Fragment 或者 Navigation 的 bug,我們會(huì)盡快處理。