1. 程式人生 > >Activity的生命週期和啟動模式詳解

Activity的生命週期和啟動模式詳解

Activity生命週期經典圖解:


按鍵對生命週期的影響:

BACK鍵:

  當我們按BACK鍵時,我們這個應用程式將結束,這時候我們將先後呼叫onPause()->onStop()->onDestory()三個方法。

再次啟動App時,會執行onCreate()->onStart()->onResume()

HOME鍵:

  當我們開啟應用程式時,比如瀏覽器,我正在瀏覽NBA新聞,看到一半時,我突然想聽歌,這時候我們會選擇按HOME鍵,然後去開啟音樂應用程式,而當我們按HOME的時候,Activity先後執行了onPause()->onStop()這兩個方法,這時候應用程式並沒有銷燬。

而當我們從桌面再次啟動應用程式時,則先後分別執行了onRestart()->onStart()->onResume()三個方法。

一般Activity切換正常生命週期(這裡的一般是指啟動模式為standard,切換activity時沒有加flag標誌):

ActivityA啟動ActivityB:

ActivityA 的生命週期onPause()->onStop(),

ActivityB的生命週期onCreate()->onStart()->onResume()。

ActivityB執行finish返回ActivityA:

ActivityB的生命週期onPause()->onStop()->onDestory()

ActivityA的生命週期了onRestart()->onStart()->onResume()

注意:當ActivityB定義為Dialog樣式時,ActivityA的生命週期是不一樣的,

我們給ActivityB加上theme

  <style name="MyDialogStyle">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:backgroundDimEnabled">true</item>
    </style>

這個時候,ActivityA啟動ActivityB,B沒有完全遮擋A,ActivityB的生命週期跟剛才一樣,但是ActivityA並沒有執行onStop()

還有一點需要特別注意,Activity中直接彈dialog,Acitivity的生命週期是不會變化的。網上有些說法是會執行onPause(),其實並沒有執行!

另外還有幾個跟生命週期相關的方法

  @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }
	
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }



當應用執行起來後就會開啟一條執行緒,執行緒中會執行一個任務棧,當Activity例項建立後就會放入任務棧中。Activity啟動模式的設定在AndroidManifest.xml檔案中,通過配置Activity的屬性android:launchMode=""設定。

1. Standard模式(預設)

我們平時直接建立的Activity都是這種模式的Activity,這種模式的Activity的特點是:只要你建立了Activity例項,一旦啟用該Activity,則會向任務棧中加入新建立的例項,退出Activity則會在任務棧中銷燬該例項。
standard模式是所啟動的Activity都是在同一個task容器棧下,不會重新建立新的task容器棧。先壓入棧的Activity例項按順序入棧底,後入棧在棧頂,處於棧的頂部Activity例項處於活動狀態,其他處於非活動狀態。按物理返回鍵,退出當前所處活動狀態Activity視窗,這樣就會從task容器棧中彈出,顯示在手機主螢幕上,從而,有非活動狀態轉換成活動的狀態。其次,standard容器棧可能會存在著相同的Activity例項,只有沒呼叫一次startActivity方法,就會建立目標Activity例項物件壓入task容器棧。
如果Activity啟動順序為A->B->B->A->D,棧中的Acitivy為ABBAD(最先建立的A位於棧底,最後建立的D位於棧頂)

2. SingleTop模式

這種模式會考慮當前要啟用的Activity例項在任務棧中是否正處於棧頂,如果處於棧頂則無需重新建立新的例項,會重用已存在的例項,否則會在任務棧中建立新的例項。
SingleTop有個不錯的用法是防止多次點選建立多個Activity,無論start幾次,SingleTop模式能保證棧頂只有一個例項。 如果Activity啟動順序為A->B->B->A->D,棧中的Acitivy為ABAD(當B位於棧頂時,再次啟動B的時候,B不會重新建立)

3. SingleTask模式

如果任務棧中存在該模式的Activity例項,則把棧中該例項以上的Activity例項全部移除,呼叫該例項的newInstance()方法重用該Activity,使該例項處於棧頂位置,否則就重新建立一個新的Activity例項。
singletask模式,特別需要注意了。啟動的目標Activity例項如果已經存在task容器棧中,不管當前例項處於棧的任何位置,是棧頂也好,棧底也好,還是處於棧中間,只要目標Activity例項處於task容器棧中,都可以重用該Activity例項物件,然後,把處於該Activity例項物件上面全部Activity例項清除掉,並且,task容器棧中永遠只有唯一例項物件,不會存在兩個相同的例項物件。所以,如果你想你的應用不管怎麼啟動目標Activity,都只有唯一一個例項物件,就使用這種啟動模式。 如果Activity啟動順序為A->B->B->A->D,棧中的Acitivy為AD(當A再次被啟動時,A會被移到棧頂,位於A上面的Acitivity全部會出棧)

4. SingleInstance模式

當該模式Activity例項在任務棧中建立後,只要該例項還在任務棧中,即只要啟用的是該型別的Activity,都會通過呼叫例項的newInstance()方法重用該Activity,此時使用的都是同一個Activity例項,它都會處於任務棧的棧頂。此模式一般用於載入較慢的,比較耗效能且不需要每次都重新建立的Activity。
singleInstance啟動模式,簡單說就是可以共享某個Activity。比如,應用1的任務容器棧中建立了MainActivity例項,應用2也要啟用MainActivity,則不需要建立MainActivity例項,直接可以公用MainActivity例項。 尤其值得注意:應用1啟動MainActivity,按home鍵;開啟應用2啟動應用1的MainActivity例項。在按home鍵,開啟應用1,這時候應用1的介面是應該是處於MainActivity介面例項。 SingleInstance的一個任務棧中只有一個Activity,並保證不再有其他Activity例項進入。

特別需要注意的生命週期onNewIntent
當一個Activity被start,而不需要重新建立時,就會執行onNewIntent生命週期。如果一個Activity的啟動模式是SingleTask,我們可以在onNewIntent中執行一些重新整理操作等。
我們一般會把MainAcitivy設定為SingleTask,除了保證MainActivity的唯一,還可以利用singleTask的特性做一些清理工作。自動管理棧,銷燬無用的Acitivity.

Intent Flags 

Flags: 表示Intent的標誌位,常用於Activity的場景中,它和Activity的啟動模式有著密切的聯絡。
下面列舉的是和本文主題相關的Flags屬性:

Intent.FLAG_ACTIVITY_NEW_TASK (預設)

預設的跳轉型別,它會重新建立一個新的Activity,不過與這種情況,比如說Task1中有A,B,C三個Activity,此時在C中啟動D的話,如果在AndroidManifest.xml檔案中給D添加了Affinity的值和Task中的不一樣的話,則會在新標記的Affinity所存在的Task中壓入這個Activity。如果是預設的或者指定的Affinity和Task一樣的話,就和標準模式一樣了啟動一個新的Activity.

FLAG_ACTIVITY_SINGLE_TOP

這個FLAG就相當於啟動模式中的singletop,例如:原來棧中結構是A B C D,在D中啟動D,棧中的情況還是A,B,C,D。

FLAG_ACTIVITY_CLEAR_TOP

這個FLAG就相當於啟動模式中的SingleTask,這種FLAG啟動的Activity會把要啟動的Activity之上的Activity全部彈出棧空間。例如:原來棧中的結構是A B C D ,從D中跳轉到B,棧中的結構就變為了A B了。

FLAG_ACTIVITY_BROUGHT_TO_FRONT

這個網上很多人是這樣寫的。如果activity在task存在,拿到最頂端,不會啟動新的Activity。這個有可能會誤導大家! 他這個FLAG其實是這個意思!比如說我現在有A,在A中啟動B,此時在A中Intent中加上這個標記。此時B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式啟動,此時在B中再啟動C,D(正常啟動C,D),如果這個時候在D中再啟動B,這個時候最後的棧的情況是 A,C,D,B。如果在A,B,C,D正常啟動的話,不管B有沒有用FLAG_ACTIVITY_BROUGHT_TO_FRONT啟動,此時在D中啟動B的話,還是會變成A,C,D,B的。

FLAG_ACTIVITY_NO_USER_ACTION

onUserLeaveHint()作為activity週期的一部分,它在activity因為使用者要跳轉到別的activity而要退到background時使用。比如,在使用者按下Home鍵,它將被呼叫。比如有電話進來(不屬於使用者的選擇),它就不會被呼叫。
那麼系統如何區分讓當前activity退到background時使用是使用者的選擇?
它是根據促使當前activity退到background的那個新啟動的Activity的Intent裡是否有FLAG_ACTIVITY_NO_USER_ACTION來確定的。
注意:呼叫finish()使該activity銷燬時不會呼叫該函式

FLAG_ACTIVITY_NO_HISTORY

意思就是說用這個FLAG啟動的Activity,一旦退出,它不會存在於棧中,比如原來是A,B,C這個時候再C中以這個FLAG啟動D的,D再啟動E,這個時候棧中情況為A,B,C,E。

Activity相關屬性taskAffinity

Activity 中的 android:taskAffinity 這個屬性介紹:
Activity為Task擁有的一個affinity。擁有相同的affinity的Activity理論上屬於相同的Task(在使用者的角度是相同的“應用程式”)。Task的affinity是由它的根Activity決定的。 
affinity決定兩件事情——Activity重新宿主的Task(參考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK標誌啟動的Activity宿主的Task。
預設情況,一個應用程式中的所有Activity都擁有相同的affinity。捏可以設定這個特性來重組它們,甚至可以把不同應用程式中定義的Activity放置到相同的Task中。為了明確Activity不宿主特定的Task,設定該特性為空的字串。

如果這個特性沒有設定,Activity將從應用程式的設定那裡繼承下來(參考<application>元素的taskAffinity特性)。應用程式預設的affinity的名字是<manifest>元素中設定的package名。

歡迎掃描二維碼,關注公眾號


相關推薦

Activity生命週期啟動模式

Activity生命週期經典圖解: 按鍵對生命週期的影響: BACK鍵:   當我們按BACK鍵時,我們這個應用程式將結束,這時候我們將先後呼叫onPause()->onStop()->onDestory()三個方法。 再次啟動App時,會執行onCr

Activity生命週期啟動模式

Activity的生命週期都很熟知,但一些特殊情況下是走的哪些方法呢? 最普通的,第一次啟動一個Activity onCreat ---onStart---onResume 開啟新的Activity或切換的桌面:onPause ----onStop(如果新的Activi

Activity生命週期啟動模式再解析

目錄 前言 前言 這篇文章寫於幾個月之前,當時有事給耽擱了,放在草稿箱裡居然給忘了,今天翻了翻部落格才想起來,連忙抽時間補全了。這是一篇基礎的理論知識,看起來會有點枯燥,相信很多朋友也都是瞭

《Android 開發藝術探索》讀書筆記(一)——Activity生命週期啟動模式

Activity 作為 Android 四大元件之首,它作為和使用者互動的介面,在開發中使用得可謂極其頻繁,所以弄清楚 Activity 的生命週期和啟動方式是非常重要的,要牢記。 1 Activity 的生命週期全面分析 1.1 典型情況下的生命週期分析 onCrea

Activity生命週期啟動模式

Activity的生命週期分析 典型情況下的生命週期。是指在使用者參與的情況下,Activity所經過的生命週期的改變。 異常情況下的生命週期。是指Activity被系統回收或者由於當前裝置的Configuration發生改變從而導致Activity被銷燬重建,異常情況下的生命週期的關注點和典型情況略有不同

Android開發藝術探索筆記(一) Activity生命週期啟動模式(1)

Activity作為Android開發中最常用的一個元件,是Android開發人員必須熟悉且掌握的重要內容。同時Activity也是在面試中經常被問到的一個方向。因此,掌握Activity的重要性也不言而喻。這或許也是為什麼任大神會在《Android開發藝術探索

開發藝術探索——第一章:Activity生命週期啟動模式

目錄 1.1 Activity 的生命週期和啟動模式 1.1.1 典型情況下的生命週期分析 1.1.2 異常情況下的生命寧週期分析 1.2 Activity 的啟動模式 1.2.1 Activity 的 LaunchMode 1.2.2 Activity 的Flags

第一章 Activity生命週期啟動模式

生命週期 一、正常情況下的生命週期 1、onCreate()和onDestroy()是配對的,標誌著Activity的建立與銷燬 onStart()和onStop()是配對的,標誌著Activity是否可見 onResume()和onPause()是配對

Android面試題(一)——Activity生命週期啟動模式

引言 這份面試題系列文章旨在查漏補缺,通過常見的面試題發現自己在Android基礎知識上的遺漏和欠缺,驗證所學是否紮實。 這是系列的第一章,後面我會根據安卓知識模組分類併網羅分析各種常見面試題。 面試題: Activity的生命週期 答

回顧基礎知識--第一章:Activity生命週期啟動模式

最近在讀任玉剛的Android開發藝術探索,為了方便之後複習,下面做一下筆記.對於Activity的生命週期相信知道安卓的最熟悉不過了,但是,我還是有了新的認識.之前,認為在onResume()時Act

Activity生命週期啟動模式

目錄 一、生命週期 Activity的各種生命週期 onSaveInstanceState() 與 onRestoreInstanceState() Activity生命週期的變化 二、啟動模式

vue2.0專案實戰(4)生命週期鉤子函式

最近的專案都使用vue2.0來開發,不得不說,vue真的非常好用,大大減少了專案的開發週期。在踩坑的過程中,因為對vue的生命週期不是特別瞭解,所以有時候會在幾個鉤子函式裡做一些事情,什麼時候做,在哪個函式裡做,我們不清楚。 下面來總結一下vue的生命週期。 vue生命週期簡介 咱們從上圖可以很明顯的看出

Activity生命週期啟動模式——程式碼實踐篇

一、概述本篇主要簡單介紹一下activity的生命週期和啟動模式。同時,我們會用程式碼實踐在不同的啟動模式下,生命週期的具體執行方式。二、Activity的生命週期首先,讓我們看一下關於Activity生命週期的一張經典圖片:在講Activity生命週期之前,我們先需要理解三

Android 開發藝術探索筆記之一 -- Android 的生命週期啟動模式

學習內容: Activity 的生命週期和啟動模式以及 IntentFilter 的匹配規則分析 異常情況下的生命週期 Activity 的啟動模式以及 Flags 隱式啟動下的 Intent 匹配 Activity 的生命週期全面分析

Activity 生命週期回撥方法

前文《 Activity(Intent-filter詳解及跳轉) 》我們瞭解了Activity的跳轉,從一個Activity跳轉到另一個Activity。剛開始接觸Activity的時候,我們的setContenview都是寫在onCreate方法中的。這個on

Android筆記:Activity生命週期以及啟動模式

Activity生命週期 activity的生命週期: onCreate        onStart           onRestart        onResume       onPaus

Android零基礎入門第77節:Activity任務棧啟動模式

csdn rpi activit 元素 進入 see 簡單 auto mar 通過前面的學習,Activity的基本使用都已掌握,接下來一起來學習更高級的一些內容。 Android采用任務棧(Task)的方式來管理Activity的實例。當啟動一個應用時,A

活動2(生命週期啟動模式)

一.活動的生命週期 為了在活動生命週期的各個階段之間導航轉換,Activity類提供了六個回撥的核心方法:onCreate(),onStart(),onResume(),onPause(),onStop()和onDestroy()。當活動進入新狀態時,系統會呼叫每個回撥。 完整的生命週

Activity的四種載入模式(standard singleTop singleTask singleInstance)

最簡單的理解 activity的四種載入模式 在android的多activity開發中,activity之間的跳轉可能需要有多種方式,有時是普通的生成一個新例項,有時希望跳轉到原來某個activity例項,而不是生成大量的重複的activity。載入模式便是決定以哪種方式啟動一個

Activity生命週期堆疊管理

Activity的生命週期 Activity是android中的四大元件之一,也是最基本,最重要的元件,是android系統提供一個視覺化的,能與使用者交換的元件。 系統提供的元件,不需要使用者例項化,使用者也不能例項化,是系統進行回撥,例如web開發的servlet也是系