當前位置:首頁 » 安卓系統 » android回退棧

android回退棧

發布時間: 2022-12-23 08:56:09

A. Android activity中載入了webview,頁面跳轉後總是要點擊兩次手機的返回按鈕才能回到上一頁

WebViewClient中的shouldOverrideUrlLoading方法如下重寫:

java">@Override
(WebViewview,Stringurl)
{
view.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
view.loadUrl(url);
returnsuper.shouldOverrideUrlLoading(view,url);
}

onKeyDown如下重寫:

@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent)
{
if(keyCode==KeyEvent.KEYCODE_BACK){
if(webView.canGoBack()){
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.goBack();
returntrue;
}else{
finish();
returntrue;
}
}
returnfalse;
}

B. android 怎麼通知回退棧中的fragment刷新

到的問題:
通過FragmentTransaction的replace方法會導致,每次都會重新調用fragment的onCreateView()方法,浪費時間。

解決方法:
通過FragmentTransaction的hide和show方法來實現fragment的顯示和隱藏,這樣就不會重復調用onCreateView函數了。

FragmentTransactioin 可以用來添加,刪除fragment,也可以控制fragment的顯示和隱藏。

這是如果調用addToBackStack(null),此時的狀態就會被保存在回退棧,按返回鍵的時候就會顯示出棧頂的

getSupportFragmentManager().popBackStack() 這個方法可以讓棧頂的fragment出棧。

只有在程序運行時被動態添加的fragment才會被添加到後退棧。
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, newFragment,"testa")
.addToBackStack(null)
.commit();

程序跑起來之後,通過這個方法後退棧數才會加一,如果在代碼中一口氣添加多個,再運行程序,getSupportFragmentManager().getBackStackEntryCount()得到的後退棧數值為零。

C. Android基礎之Activity 運行模式與回退棧

LaunchMode 定義的是activity實例與task之間的關系,可以通過下面的兩種方式來定義:

在Activity A中啟動B,可以利用Activity B在清單中的launchmode定義,也可以在A中調用startActivity()的時候通過intent的flag傳入,當兩種方式都有定義,intent的flag參數會覆蓋掉B原有的定義。

利用Activity 元素的launchMode屬性
launchMode屬性指定Activity如何被運行到一個task中。launchMode的值有四種:

默認, 每次啟動Activity系統都會產生一個新的實例,並且把intent發送給新產生的實例,這個Activity可以被實例化多次,每個實例可以屬於不同的task,每個task也可以保有多個此Activity的實例。

如果當前task 的回退棧棧頂已經存在一個此Activity的實例,系統通過調用這個實例的onNewIntent()方法把intent發送給這個Activity實例,而不是創建一個新的此Activity的實例。這個Activity也可以被實例化多次,每個實例可以屬於不同的task,每個task可一個保有多個實例(僅限於此Activity已存在的實例不在棧頂)
注意:
應用場合如下:不想出現2個同樣的activity在頂部。比如用戶正在一個activity閱讀信息,這時來了notification,用戶點擊後應該更新這些信息,而不是新建一個activity,這樣在點擊back時,就不會出現回到舊信息activity的情況了。這種情況正是下面這段英語提到的。
Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent()
.
例如,當前回退棧中有A,B,C,D四個Activity,全部是Standard,在D中調用startActivity()去啟動B,intent的flag設置成FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK,系統發現棧中有B,會先銷毀這個B,再原位置重建B,清空CD,而不是把這個新建的B的實例壓入棧頂,這里之所以會銷毀B再新建B,因為B的launchmode是Standard,無論什麼情況下啟動,都需要new一個B的實例,但如果此時B是SingleTop的,系統會把這個intent通過onNewIntent傳給已經在棧中的B的實例,不需要銷毀再創建,仍需要清空CD。

系統會創建一個新的task並且把這個實例放在棧底( 此處有疑問,測試發現並不一定是棧底 ),但是,如果在一個單獨的task中已經存在一個此Activity的實例,系統會把intent通過onNewIntent()發送給這個實例( 測試發現如果在回退棧中,該Activity的上面還有其他Activity,啟動此Activity會清空棧中此Activity上面的其他Activity ),而不是創建一個新的實例。同一時間在只有一個此Activity的實例存在於系統中。

與SingleTask一樣,不同的是SingleTask的Activity所在的task中可以有其他的Activity,而SingleInstance的Activity獨佔一個task,並且在整個系統中只有唯一的一個實例。由這個Activity啟動的其他Activity都會在新的task中打開。

另一個例子,系統自帶瀏覽器APP把瀏覽器Activity聲明為SingleTask,通過在Activity標簽里的launchMode進行指定,這意味著如果你發送一個intent啟動瀏覽器,不管是為瀏覽器新開啟一個task還是從瀏覽器已經在後台保有的task中啟動瀏覽器,瀏覽器Activity與你的APP不在同一個task。

不管一個Activity是不是在一個新的task中啟動,點擊返回都會返回前一個Activity。不過,如果啟動一個LaunchMode為singleTask的Activity,如果該Activity此時在一個處於後台的task中,整個task會變成前台task,此時,回退棧會包含由這個後台task攜帶過來所有Activity,放在回退棧的棧頂,下圖說明這種情況。

在一個新的task里啟動Activity. 如果已經有Activity實例運行在某一task中,啟動這個Activity會把該實例所在的task帶到前台,由該實例的onNewIntent()來接收新的intent。

如果被啟動的Activity就是當前的Activity,這個已經存在的實例通過onNewIntent()接收intent,不會產生新的實例。

被啟動的Activity如果已經存運行於當前task,回退棧中所有在此Activity上面的Activity都將被銷毀,此Activity通過onNewIntent()接收新的intent。
例如,一個task中有A,B,C,D,四個Activity,如果D 調用startActivtiy()啟動Activity B,C和D會被銷毀,B接收這個intent,回退棧中有A,B。
上例中的Activity B的實例,或者通過onNewIntent()接收新的intent,或者銷毀新建來處理新的intent。如果B的launchmode是standard,並且沒有設置FLAG_ACTIVITY_SINGLE_TOP,那麼B會被銷毀重啟,如果是其他launchmode或者設置了FLAG_ACTIVITY_SINGLE_TOP,則會通過onNewIntent()接收。
FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK結合使用會有個不錯的效果。
如果啟動的Activity位於task的底部,它會把所在task帶到前台,並且清理狀態至root狀態,當從通知欄里打開一個Activity的會非常有用。

Affinity指的是一個Activity偏向於從屬於哪個task,默認情況下,一個APP內的所有Activity互相之間共享一個affinity的值,所以,所有同一APP下的所有Activity都偏向於從屬於同一個task。但是,這個值是可以更改的,不同APP內的Activity可以共享一個affinity,同一個APP內的Activity也可以被分配不同的affinity的值。
affinity的值可以通過修改Activity標簽的taskAffinity屬性來修改。
這個屬性接收一個String的值,必須在manifest標簽范圍內是唯一的值,因為系統是通過名稱來標識APP的affinity的值的。
Affinity作用於以下兩種情況:

通過startActivity()啟動一個新的Activity時,默認情況下,新的Activity會被壓入與啟動者相同的回退棧中。但是,如果在啟動Activity的時候,使用了FLAG_ACTIVITY_NEW_TASK 這個標志,系統會為新的Activity尋找一個新的task。通常情況下,是一個新的task。但是也並不是必須的。如果系統中有一個task的affinity值與新的Activity的值相同,新的Activity會被分配到這個task中。如果沒有這樣的task,就啟動一個新的task。如果這個標志產生了一個新的task,當用戶點擊home鍵離開的時候,必須要有某種方式能夠使用戶返回到這個task來。有些實體(例如通知管理器)總是從一個外部task中啟動Activity,所以在通過startActivity()啟動新的Activity時總是需要傳遞FLAG_ACTIVITY_NEW_TASK 這個標志。如果你有一個Activity可以被外部實體可能這個標志啟動,注意用戶可以有一種獨立的方式回到啟動它的task,例如點擊啟動圖標。

這種情況下,一個Activity可以動啟動它的那個task移動到它的affinity值對應的task中,當那個task回到前台。例如,假設,一個報告指定城市天氣情況的Activity作為一個旅行APP的一部分,它跟其他處在同一APP的Activity一樣有一個相同的affinity值,並且允許通過這個屬性來調整目標task。當你的一個Activity啟動了這個天氣預報Activity,它默認跟你的Activity在一個task里,但是,當旅行APP進入到前台,這個天氣預報Activity又會被重新分配給旅行APP並且在旅行APP內展示。
提示:
如果一個APK文件從用戶的角度看是多款APP,可能需要這個屬性來設置不同的affinity來關聯不同的APP。

如果用戶離開一個task太長時間,系統會清除task中的所有Activity僅僅保留這下根Activity。當用戶返回到這個task的時候,只有這個根Activity會被恢復。系統通過這種方式來處理,是因為經過相當長的一段時間之後,用戶已經拋棄他們曾經正在做的事情,計劃再回來的時候做點新的事情。

你可以通過如下屬性來更改這種行為:

參考文獻:
Tasks and Back Stack
<activity>
Android 閱讀Tasks and Back Stack文章後的重點摘抄

熱點內容
空間新演算法 發布:2025-04-05 10:33:21 瀏覽:704
蜀門和遠征哪個配置低 發布:2025-04-05 10:23:50 瀏覽:284
linux下jdk的安裝 發布:2025-04-05 10:12:20 瀏覽:67
單機江湖腳本 發布:2025-04-05 10:08:32 瀏覽:764
愛奇藝離線緩存怎麼傳藍牙 發布:2025-04-05 10:00:48 瀏覽:140
阿里雲伺服器內存超頻 發布:2025-04-05 10:00:48 瀏覽:575
如何登錄pubg國際服安卓手機 發布:2025-04-05 09:40:07 瀏覽:413
javafor表達式 發布:2025-04-05 09:22:22 瀏覽:869
可逆的加密演算法 發布:2025-04-05 09:22:22 瀏覽:496
我的世界怎麼讓別人進我的伺服器 發布:2025-04-05 09:11:59 瀏覽:802