android Activity生命周期(設備旋轉、數據恢復等)與啟動模式

来源:http://www.cnblogs.com/gzdaijie/archive/2016/03/08/5255084.html
-Advertisement-
Play Games

作者: "@gzdaijie" 本文為作者原創,轉載請註明出處:http://www.cnblogs.com/gzdaijie/p/5255084.html 目錄 1.Activity生命周期 1.1 Activity生命周期簡介與測試 1.2 設備旋轉時的生命周期與數據恢復 1.3 Activit


作者:@gzdaijie
本文為作者原創,轉載請註明出處:http://www.cnblogs.com/gzdaijie/p/5255084.html

目錄

1.Activity生命周期
1.1 Activity生命周期簡介與測試
1.2 設備旋轉時的生命周期與數據恢復
1.3 Activity暫存與Activity記錄
2.Activity啟動模式
2.1 standard
2.2 singleTop
2.3 singleTask
2.4 singleInstance

1.Activity生命周期

    接下來將介紹 Android Activity(四大組件之一) 的生命周期, 包含運行、暫停和停止三種狀態,onCreate、onStart、onResume、onPause、onStop、onDestroy六種系統調用方法。

1.1 Activity生命周期簡介與測試

生命周期

    如圖所示,Activity實例可以在生命周期狀態發生關鍵性轉換時完成某些工作。

  • onCreate() 創建,該方法是最常被覆蓋的方法,第一次創建實例時調用, 一般用來完成實例創建的初始化操作,包括實例化組件,設置監聽器,訪問外部模型數據等。
  • onStart() 開始,當Activity處於可見狀態的時候就會調用onStart方法,包括創建完實例顯示,或者從其他活動切換到活動時調用。
  • onResume() 準備,當Activity獲得用戶焦點時調用。
  • onPause 暫停,當Activity準備調用或者恢復另一個活動時調用,失去焦點時,例如啟動一個Dialog調用。該方法可以釋放一些消耗CPU的資源,保存一些關鍵數據,但是執行速度要快,否則影響新的棧頂活動使用。
  • onStop 停止,完全不可見時調用。例如成功啟動了另外一個活動,該活動離開棧頂不可見。啟動Dialog不會執行該方法。
  • onDestroy 銷毀,這個方法在活動銷毀時調用。
// 可以使用以下方法進行測試。
public class MainActivity extends Activity {
    
    private String TAG = "MainActivity";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG,"Create");
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "Start");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "Resume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "Pause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "Stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Destroy");
    }
}

1.2 設備旋轉時的生命周期與數據恢復

設備旋轉

    使用上面的日誌列印測試方法發現, 設備旋轉時生命周期如圖所示,即設備旋轉時,當前活動實例會被系統銷毀,然後創建一個新的實例。

    因為旋轉設備會改變設備配置(device configuration),設備配置包括屏幕的方向、密度、尺寸、鍵盤類型、底座模式等,為匹配不同的設備,可以使用不同的佈局文件,這和Web開發中 針對不同寬度的屏幕選擇不同CSS樣式異曲同工,如何創建不同佈局適配不同配置設備不在本文討論之列。

    設備旋轉時,臨時數據會丟失。例如你使用了一個變數記錄了用戶點擊了多少次按鈕,設備旋轉之後,Activity重新創建,這個變數就被初始化了,這裡可以使用Bundle對象來恢復。保存數據可以覆蓋onSaveInstanceState()方法。

    例如下麵的代碼,按3次按鈕,旋轉屏幕後,將列印出saved currentPage:3 init mCurrentPage:0,點擊次數存在了Bundle對象中,併在onCreate()中獲取到。

/*
 * onSaveInstanceState()通常在onPause、onStop、onDestroy前由系統調用
 * onCreate()傳入的參數savedInstanceState可獲取保存的變數
 */
public class MainActivity extends Activity {

    private static final String KEY = "currentPage";
    private static final String TAG = "MainActivity";
    private Integer mCurrentPage = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCurrentPage += 1;
            }
        });
        if(savedInstanceState != null){
            // 列印使用Bundle保存的currentPage信息
            Log.d(TAG,"saved currentPage: " + savedInstanceState.getInt(KEY,0));
            // 列印新建活動mCurrentPage的值,總為0
            Log.d(TAG,"init mCurrentPage: " + mCurrentPage);
            // ... update code
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 使用key-value對的方式存儲臨時變數
        outState.putInt(KEY, mCurrentPage);
    }
}

1.3 Activity暫存與Activity記錄

    當系統回收記憶體時,處於Pause、Stop狀態的Activity可能被銷毀,此時系統會調用onSaveInstanceState(),用戶數據被存儲在Bundle對象中,系統將Bundle對象放入Activity記錄,可以將這種狀態理解為Activity的暫存狀態(無實例有記錄)。

    Activity暫存後,當前活動不復存在,Activity記錄可幫助用戶返回應用時活動的快速恢復,提供一個好的用戶體驗。但是當用戶按了後退鍵,系統會徹底銷毀當前活動,Activity記錄同時被清除,系統重啟也會被清除該記錄。

2.Activity啟動模式

2.1 standard(預設)

     standard是活動預設的啟動模式,Android是使用返回棧來管理活動的,所謂棧就是先進後出,後進先出。該模式下,每啟動一個新的活動,就會在返回棧中入棧,並處於棧頂的位置(即用戶當前見到的活動)。系統不會 檢查該活動的實例已經在返回棧中存在,每次啟動都新建一個。當前返回棧為A->B(B為棧頂),新建活動B, 返回棧變為A->B->B。

2.2 singleTop

    standard模式有時並不合理,比如活動實例已經在棧頂了,再次啟動時還需再創建一個實例, 這會造成資源的浪費。singleTop模式下,如果當前棧頂已經是該活動實例,則認為可以直接使用,而不再創建新的活動。當前返回棧為A->B(B為棧頂),新建活動B, 返回棧仍為A->B。

<!--AndroidManifest.xml-->
<!--設置方式,launchMode -->
<activity android:name=".MainActivity"
    android:launchMode="singleTop"
    android:label="AndroidDialog">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

2.3 singleTask

    singleTop模式可以避免重覆創建棧頂活動的問題,但是如果啟動活動不在棧頂,而之前已經創建過,還是會重覆創建。例如A->B->C,當前已有三個活動A、B、C,C位於棧頂,再創建B,返回棧變為A->B->C->B(另一個實例)。singleTask模式可以讓返回棧中每個活動只存在一個實例,如果發現當前需要啟動活動已經在棧中,則直接使用,但是該活動之上的所有活動全部出棧;如沒有發現,則創建新的實例。例如A->B->C,如此時創建活動B,則返回棧變為A->B(B存在,使用B,C出棧);若此時創建活動D,則返回棧變為A->B->C->D

2.4 singleInstance

    singleInstance模式是四種啟動模式中最複雜的,不同於上述三種模式,指定為singleInstance模式的活動會啟動一個新的返回棧來管理這個活動。例如當前有活動A、B、C,活動A、C為預設啟動模式,B指定為singleInstance模式,首先新建A,A活動頁面啟動B,B啟動C,此時的返回棧並不是A->B->C,而是存在2個返回棧,一個是A->C,另一個是B。此時按下BACK鍵返回,將從C返回到A,再按一次,A返回到B,按第三次,程式退出。即返回時,先清空棧A->C,再清空棧B。
    singleInstance模式有什麼應用場景呢?例如當前程式中某個活動允許其他活動調用,如果想多個程式共用該活動的一個實例A,那麼每一個程式都有一個返回棧,若使用前3種模式,該活動入棧時必然創建新的實例,無法實現實例共用。singleInstance能很好地解決這個問題。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一:需求分析 1)需要首頁,末頁功能 2)有點擊查看上一頁,下一頁功能 3)頁碼到當前可視頁碼最後一頁刷新頁面 二:功能實現思路 也是分為三部分處理 1)點擊首頁,末頁直接顯示第一頁或者最後一頁內容,當前頁面為第1頁或者最後一頁。隱藏首頁或者末頁按鈕。demo 顯示截圖 首頁狀態 和 末頁狀態代碼執
  • HTML 教程 HTML 簡介 html div 標簽介紹 html span 標簽介紹 html a 超鏈接標簽 HTML Br換行標簽介紹 HTML P段落標簽介紹 HTML br與p標簽區別 Html H 標題標簽 html px em pt長度單位 HTML B 加粗標簽 HTML stro
  • 在很多現實的場景中,有的文本框我們希望在選擇“是”的按鈕之後才出現,這就需要js控制TR的隱藏和顯示,如何控制,本文為大家揭曉 下文分享的一段代碼:選擇是的按鈕就顯示身高和體重的文本框的代碼。註意:ready方法必須要引用jquery的庫。 1.html Code <html> <head> <me
  • 看到網上很多展示html5雪花飛動的效果,確實非常引人入勝,我相信大家也跟我一樣看著心動的同時,也很好奇,想研究下代碼如何實現;雖然哦很多地方也能下載這些源碼,不過也不知道別人製作此類動畫時的思路及難點分析。 我這幾天剛好學習了一下,也趁著此刻有時間從需求分析、知識點、程式編寫一步步給大家解剖下。
  • 1. css屬性命名區分大小寫嗎? 不區分,不過一般小寫,便於理解 2. margin-top和margin-bottom對於行內(內斂inline)元素效果一樣麽? 3.padding-top和padding-bottom對於inline元素都會增加元素本身的大小麽? 回答2,3,需要瞭解html...
  • 我們知道任何一個自定義函數都是Function構造器的實例,所以我們可以通過new Function的方式來創建函數,使用語法很簡單, new Function(形參1, 形參2, ..., 形參N, 函數體) 註意,裡面的參數全部是以字元串的形式呈現。比如一個簡單的例子——要求寫一個函數, 求兩個
  • ShineJaie 原創,轉載請註明出處。 昨晚在一個交流群里看到有位網友提了一個他的面試題求助答疑。剛好我也有看到,就對這個問題思考了一下,覺得這道題對理解 JavaScript 作用域還是很有幫助的,特此又把自己的解題思路梳理了一遍,希望對其它人有所幫助。 首先看下麵試題: 1 var arr
  • jQuery 2 的版本與jQuery 1的版本相比,沒有再考慮IE6,7,8的相容問題,因此使用時如果不用考慮IE6,7,8就用jQuery 2的版本,如果需要考慮IE6,7,8就使用jQuery 1的版本。 jQuery對象是一個以DOM為對象的特殊數組,並包含大量方法,簡單可以理解為: fun...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...