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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...