Android應用開發—onSaveInstanceState方法什么時候被調用?

轉載自onSaveInstanceState方法什么時候被調用?(轉載/整理)

  • 在 Activity 被銷毀之前被調用來保存每個實例的狀態,這樣就可以保證該狀態能夠從 onCreate(Bundle) 或者onRestoreInstanceState(Bundle)恢復過來。 本方法在 Activity 可能被銷毀前調用,這樣當該 Activity 在將來某個時刻重新回來時可以恢復其之前的狀態。例如,如果 Activity B 啟用后位于 Activity A 的前端,在某個時刻 Activity A 因為系統回收資源的原因要被銷毀,Activity A 有機會通過 onSaveInstanceState() 來保存其用戶界面狀態,使得將來用戶返回到 Activity A 的時候能夠通過 onCreate(Bundle) 或者onRestoreInstanceState(Bundle) 來恢復其界面狀態。不要將這個方法和 Activity 生命周期中的回調如 onPause() 或 onStop() 搞混淆了,onPause() 在 Activtiy 被放置到后臺或者自行銷毀時總會被調用,onStop() 在 Activity 被銷毀時被調用。一個會調用 onPause() 和 onStop() 但不會觸發 onSaveInstanceState() 的例子是當用戶從 Activity B 返回到 Activity A 時:沒有必要調用 B 的 onSaveInstanceState(Bundle)方法,因為此時的 B 實例永遠不會被恢復,因此系統會避免調用它。一個調用 onPause() 但不調用 onSaveInstanceState(Bundle) 方法的例子是當 Activity B 啟動后處在 Activity A 的前端:如果在B的整個生命周期里 A 的用戶界面狀態都沒有被破壞的話,系統是不會調用 Activity A 的onSaveInstanceState(Bundle)方法。默認的實現負責了大部分 UI 實例狀態的保存,采用的方式是調用 UI 層上每個擁有 id 的 view 的 onSaveInstanceState()方法 ,并且保存當前獲得焦點的 view 的 id (所有保存的狀態信息都會在默認的 onRestoreInstanceState(Bundle) 實現中恢復)。如果你覆寫這個方法來保存額外的沒有被各個view保存的信息,你可能想要在默認實現過程中調用或者自己保存每個視圖的所有狀態。如果被調用,這個方法會在 onStop() 前被觸發,但系統并不保證是否在 onPause() 之前或者之后觸發。

  • Activity 中的 onSaveInstanceState() 方法和 onRestoreInstanceState() 方法并不是生命周期方法,它們不同于 onCreate()、onPause() 等生命周期方法,它們并不一定會被觸發。當應用遇到意外情況(如:內存不足、用戶直接按Home鍵),由系統銷毀一個 Activity 時,onSaveInstanceState() 方法就會被調用。但是當用戶主動去銷毀一個 Activity 時,例如在應用中按返回鍵,onSaveInstanceState() 方法就不會被調用。因為在這種情況下,用戶的行為決定了不需要保存Activity的狀態。通常onSaveInstanceState() 方法只適合用于保存一些臨時性的狀態,而onPause() 方法適合用于數據的持久化保存。 另外,當屏幕的方向發生了改變, Activity 會被銷毀并重新創建,如果你想在 Activity 被銷毀前緩存一些數據,并且在 Activity 被重新創建后恢復緩存的數據。可以重寫 Activity 中的 onSaveInstanceState() 方法和 onRestoreInstanceState()方法,如下:

    public class PreferencesActivity extends Activity {private String name;protected void onRestoreInstanceState(Bundle savedInstanceState) {// 重新創建后恢復緩存的數據name = savedInstanceState.getString("name");super.onRestoreInstanceState(savedInstanceState);}protected void onSaveInstanceState(Bundle outState) {// 被銷毀前緩存一些數據outState.putString("name", "l_yqing");super.onSaveInstanceState(outState);}
    } 
  • 當用戶啟動一個新 Activity 之后,之前的 Activity 可能在內存中處于停止狀態也可能由于新 Activity 需要更多內存而被系統銷毀了,但不論怎樣,當用戶在新 Activity 上點擊返回鍵時,他希望看到的是原先的 Activity 的界面。原先的 Activity 如果是被重新創建的,那么它就要恢復到用戶最后看到它時的樣子,我們該怎么做呢?其實也不難,在 onPause() 、onStop() 或 onDestroy() 中保存必要的數據就行了。但是現在Google又冒出一個新的東西:onSaveInstanceState(),觀其名可知其意:它是專門用來保存實例狀態的,這個“實例”不是指的 Activity 對象,而是它所在的進程,因為Activity 的銷毀是因為它所在的進程被殺掉而造成的。onSaveInstanceState()是在系統感覺需要銷毀Activity時調用的,它被傳入一個參數Bundle,這個Bundle可以被認為是個 Map 字典之類的東西,用“鍵-值”的形式來保存數據。現在又叫人蛋疼了:不是可以在 onPause() 中保存數據嗎?為什么又搞出這樣一個家伙來?它們之間是什么關系呢? 原來,onSaveInstanceState() 方法的主要目的是保存和 Activity 的狀態有關的數據,當系統在銷毀 Activity 時,如果它希望 Activity 下次出現的樣子跟之前完全一樣,那么它就會調用onSaveInstanceState(),否則就不調用。所以要明白這一點:onSaveInstanceState() 方法并不是永遠都會調用。比如,當用戶在一個 Activity 點擊返回鍵時,就不會調用,因為用戶此時明確知道這個 Activity 是要被銷毀的,并不期望下次它的樣子跟現在一樣(當然開發者可以使它保持臨死時的表情,你非要這樣做,系統也沒辦法),所以就不用調用onSaveInstanceState()。現在應該明白了:在onPause()、onStop() 以及 onDestroy() 中需要保存的是那些需要永久化的數據,而不是保存用于恢復狀態的數據,狀態數據有專門的方法:onSaveInstanceState()。數據保存在一個 Bundle 中,Bundle 被系統永久化。當再調用 Activity 的onCreate()時,原先保存的 Bundle就被傳入,以恢復上一次臨死時的模樣,如果上次被銷毀時沒有保存 Bundle,則為 null。 還沒完呢,如果你沒有實現自己的 onSaveInstanceState(),但是 Activity 上控件的樣子可能依然能被保存并恢復。原來 Activity 類已實現了onSaveInstanceState(),在 onSaveInstanceState() 的默認實現中,會調用所有控件的相關方法,把控件們的狀態都保存下來,比如 EditText 中輸入的文字、CheckBox 是否被選中等等。然而不是所有的控件都能被保存,這取決于你是否在 layout 文件中為控件賦了一個名字(android:id)。有名的就存,無名的不管。既然有現成的可用,那么我們到底還要不要自己實現 onSaveInstanceState() 方法呢?這就得看情況了,如果你自己的派生類中有變量影響到UI,或你程序的行為,當然就要把這個變量也保存了,那么就需要自己實現,否則就不需要,但大多數情況肯定需要自己實現一下下了。對了,別忘了在你的實現中調用父類的 onSaveInstanceState() 方法。
    注:由于 onSaveInstanceState() 方法并不是在每次被銷毀時都會調用,所以不要在其中保存那些需要永久化的數據,執行保存那些數據的最好地方是在 onPause() 方法中。

轉自heiguy的專欄onSaveInstanceState和onRestoreInstanceState觸發的時機

先看Application Fundamentals上的一段話:

Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key) 從這句話可以知道,當某個activity變得“容易”被系統銷毀時,該activity的onSaveInstanceState就會被執行,除非該activity是被用戶主動銷毀的,例如當用戶按BACK鍵的時候。 注意上面的雙引號,何為“容易”?言下之意就是該activity還沒有被銷毀,而僅僅是一種可能性。這種可能性有哪些?通過重寫一個activity的所有生命周期的onXXX方法,包括onSaveInstanceState和onRestoreInstanceState方法,我們可以清楚地知道當某個activity(假定為activity A)顯示在當前task的最上層時,

其onSaveInstanceState方法會在什么時候被執行,有這么幾種情況:

  • 當用戶按下HOME鍵時。 這是顯而易見的,系統不知道你按下HOME后要運行多少其他的程序,自然也不知道activity A是否會被銷毀,故系統會調用onSaveInstanceState,讓用戶有機會保存某些非永久性的數據。以下幾種情況的分析都遵循該原則
  • 長按HOME鍵,選擇運行其他的程序時。
  • 按下電源按鍵(關閉屏幕顯示)時。
  • 從activity A中啟動一個新的activity時。
  • 屏幕方向切換時,例如從豎屏切換到橫屏時。

在屏幕切換之前,系統會銷毀activity A,在屏幕切換之后系統又會自動地創建activity A,所以onSaveInstanceState一定會被執行 總而言之,onSaveInstanceState的調用遵循一個重要原則,即當系統“未經你許可”時銷毀了你的activity,則onSaveInstanceState會被系統調用,這是系統的責任,因為它必須要提供一個機會讓你保存你的數據(當然你不保存那就隨便你了)。

至于onRestoreInstanceState方法,需要注意的是,onSaveInstanceState方法和onRestoreInstanceState方法“不一定”是成對的被調用的,onRestoreInstanceState被調用的前提是,activity A“確實”被系統銷毀了,而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調用,例如,當正在顯示activity A的時候,用戶按下HOME鍵回到主界面,然后用戶緊接著又返回到activity A,這種情況下activity A一般不會因為內存的原因被系統銷毀,故activity A的onRestoreInstanceState方法不會被執行

另外,onRestoreInstanceState的bundle參數也會傳遞到onCreate方法中,你也可以選擇在onCreate方法中做數據還原。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449999.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

記一次phpstudy重啟后Apache無法啟動

相信大家都碰到過phpstudy中Apache無法啟動的情況1、首先檢查80端口是否占用,有的話就管理2、檢查是否缺少vc9運行文件如果上述兩種方法還不能解決問題就進入安裝目錄中Apache的bin目錄下,在命令行窗口中執行httpd.exe,看看是否報錯。我就是在…

C#任務調度——LimitedConcurrencyLevelTaskScheduler

這是參考大佬分享的代碼寫的有問題請提出指正,謝謝。using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace TaskManager {class TaskFactoryMa…

同步本地遠程分支 git remote prune origin

git remote prune origin (不常用總忘記,記錄下)

264 參考幀 list0 list1

作了這么久的h264工作,這部分還一直從未去深入了解過,真是不求甚解啊,那幫老外的代碼也寫得太全了,該部分至今天才開始研究 首先參考幀這里關注的是兩種,p ,b ,前向參考和后向參考 由白皮書中看到,p幀的參…

面試官問我:什么是JavaScript閉包,我該如何回答

閉包,有人說它是一種設計理念,有人說所有的函數都是閉包。到底什么是閉包?這個問題在面試是時候經常都會被問,很多小白一聽就懵逼了,不知道如何回答好。這個問題也有很多朋友在公眾號給李老師留言了,問題表…

robotframework基礎學習(8)

變量的使用 在 Edit 標簽頁中主要分:加載外部文件、定義內部變量、定義元數據等三個部分。 (1):加載外部文件Add Library:加載測試庫,主要是[PYTHON 目錄]\Lib\site-packages 里的測試庫 Add Resource&…

版本字符串比較工具接口常用接口函數

版本升級比較常用的接口,字符串解析,不是很難,但沒必須重復造輪子,保存一份網上搜到的實現: /*** 比較版本號的大小,前者大則返回一個正數,后者大返回一個負數,相等則返回0** param version1* param version2* return…

[藍橋杯]ALGO-188.算法訓練_P0504

Anagrams指的是具有如下特性的兩個單詞:在這兩個單詞當中,每一個英文字母(不區分大小寫)所出現的次數都是相同的。例如,Unclear和Nuclear、Rimon和MinOR都是Anagrams。編寫一個程序,輸入兩個單詞&#xff0…

什么是3-2混合

正如上面所述,電影轉換成視頻時,每秒24幀必須轉成每秒60場(30幀)。實現這一點的方法是把電影的第一幀顯示3場,然后把第二幀顯示2場,再把第三幀顯示3場,以此類推。這個3-2-3-2-3-2的順序就被稱為…

shell 的here document 用法、輸入/輸出重定向

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 什么是Here Document Here Document 是在Linux Shell 中的一種特殊的重定向方式&#xff0c;它的基本的形式如下 cmd << delimiter…

beta第二天

團隊成員 鄭西坤 031602542 &#xff08;隊長&#xff09; 陳俊杰 031602504陳順興 031602505張勝男 031602540廖鈺萍 031602323雷光游 031602319吳志鴻 0316206341.昨天的困難 陳順興&#xff1a;無 廖鈺萍&#xff1a;無 吳志鴻&#xff1a;沒有 雷光游&#xff1a;無 鄭西坤…

void和void *

void f(void) { // 參數void可以省略cout << "aa"<<endl; } int t 22; int *a &t; void *p; // void *可以被賦值為其他類型 p a; cout << *(int *)p; // 使用的時候必須轉到那個類型 轉載于:https://www.cnblogs.com/pjishu/p/10343587.…

Android應用開發—Application

What is Application Application和Activity&#xff0c;Service一樣是android框架的一個系統組件&#xff0c;當android程序啟動時系統會創建一個application對象&#xff0c;用來存儲系統的一些信息。通常我們是不需要指定一個Application的&#xff0c;這時系統會自動幫我們…

C語言符號

C語言運算符的優先級 一、運算符的優先級表 C 語言的符號眾多&#xff0c;由這些符號又組合成了各種各樣的運算符。既然是運算符就一定有其特定的優先級&#xff0c;下表就是C 語言運算符的優先級表&#xff1a; 注&#xff1a;同一優先級的運算符&#xff0c;運算次序由結合…

手機按鍵中控運行思路的個人理解

目前而言基本的自己理解的中控多線程腳本無非就是兩種1.主代碼作為腳本功能的載體 另外開辟一個線程作為和中控保持聯系的部分(下面只是思路 無法直接運行)Import "zm.luae" zm.Init /* 該思路下的基本流程 從UI界面獲取到云賬號 和 本地的配置信息---->根據自己…

burp過期了,換一個

先從吾愛破解論壇下載工具&#xff1a;https://down.52pojie.cn/Tools/Network_Analyzer/Burp_Suite_Pro_v1.7.37_Loader_Keygen.zip 工具運行需要Java環境&#xff0c;請自行安裝&#xff0c;此處不贅述。解壓完后雙擊keygen 填一下License Text(隨意)&#xff0c;然后點擊Run…

加載一張圖片到ImageView到底占據多少內存

https://blog.csdn.net/BUG_delete/article/details/79557939 簡介 Android中經常要通過ImageView進行圖片資源顯示。在加載圖片時&#xff0c;首先要考慮的兩個因素就是體驗問題和性能問題。 其中&#xff0c;體驗問題是指圖片顯示的是否正確&#xff08;例如Universal-Imag…

mysql -u root -p 解釋

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 mysql -u 用戶名 -p 密碼 是連接數據庫服務器的命令。要求你輸入自己連接數據庫的用戶名和密碼。 考慮密碼如果直接明文寫在這條命令行…

hbase 概念

在hbase里面有幾個通俗的名稱會經常出現 1&#xff09;Hregion region 2&#xff09;Hregionserver regionserver 3&#xff09;Hmaster master 4&#xff09;Hmamstore memstore 5&#xff09;Hfile storeFile 1、什么是hbase&#xff1f; 1&#xff09;它是基于稀疏的、…

beta沖刺第三天

團隊成員 鄭西坤 031602542 &#xff08;隊長&#xff09; 陳俊杰 031602504陳順興 031602505張勝男 031602540廖鈺萍 031602323雷光游 031602319吳志鴻 0316206341.昨天的困難 陳順興&#xff1a;理解別人的代碼 廖鈺萍&#xff1a; 吳志鴻&#xff1a;無 雷光游&#xff1a; …