Activity作為四大組件之一,也可以說是四大組件中最重要的一個組件,它負責App的視圖,還負責用戶互動,而且有時候還經常其他組件系結使用,可以說非常的重要,
雖然說我們天天都在使用Activity,但是你真的對Activity的生命機制爛熟于心,完全了解了嗎?的確,Activity的生命周期方法只有七個(自己數-,+),但是其實那只是最平常的情況,或者說是默認的情況,也就是說在其他情況下,Activity的生命周期可能不會是按照我們以前所知道的流程,這就要說到我們今天的重點了——Activity的啟動模式:我們的Activity會根據自身不同的啟動模式,自身的生命周期方法會進行不同的呼叫,
一、在將啟動模式之前必須了解的一些知識:
在正式的介紹Activity的啟動模式之前,我們首先要了解一些旁邊的知識,這些知識如果說模糊不清,那么在討論啟動模式的時候會一頭霧水(筆者親身感悟),
- 一個應用程式通常會有多個Activity,這些Activity都有一個對應的action(如MainActivity的action),我們可以通過action來啟動對應Activity(隱式啟動),
<action android:name="android.intent.action.MAIN" />
-
一個應用程式可以說由一系列組件組成,這些組件以行程為載體,相互協作實作App功能,
-
任務堆疊(Task Stack)或者叫退回堆疊(Back Stack)介紹:
3.1.任務堆疊用來存放用戶開啟的Activity,
3.2.在應用程式創建之初,系統會默認分配給其一個任務堆疊(默認一個),并存盤根Activity,
3.3.同一個Task Stack,只要不在堆疊頂,就是onStop狀態:
3.4.任務堆疊的id自增長型,是Integer型別,
3.5.新創建Activity會被壓入堆疊頂,點擊back會將堆疊頂Activity彈出,并產生新的堆疊頂元素作為顯示界面(onResume狀態),
3.6.當Task最后一個Activity被銷毀時,對應的應用程式被關閉,清除Task堆疊,但是還會保留應用程式行程(狂點Back退出到Home界面后點擊Menu會發現還有這個App的框框,個人理解應該是這個意思),再次點擊進入應用會創建新的Task堆疊,
- Activity的affinity:
4.1.affinity是Activity內的一個屬性(在ManiFest中對應屬性為taskAffinity),默認情況下,擁有相同affinity的Activity屬于同一個Task中,
4.2.Task也有affinity屬性,它的affinity屬性由根Activity(創建Task時第一個被壓入堆疊的Activity)決定,
4.3.在默認情況下(我們什么都不設定),所有的Activity的affinity都從Application繼承,也就是說Application同樣有taskAffinity屬性,
<application android:taskAffinity="gf.zy"4.4.Application默認的affinity屬性為Manifest的包名,
暫時就是這么多了,如果還有不妥的地方我會補充的,接下來我們來正式看Activity的啟動模式:
二、Activity啟動模式:
1. 默認啟動模式standard:
該模式可以被設定,不在manifest設定時候,Activity的默認模式就是standard,在該模式下,啟動的Activity會依照啟動順序被依次壓入Task中:
上面這張圖講的已經很清楚了,我想應該不用做什么實驗來論證了吧,這個是最簡單的一個,我們過,
2. 堆疊頂復用模式singleTop:
在該模式下,如果堆疊頂Activity為我們要新建的Activity(目標Activity),那么就不會重復創建新的Activity,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zy.pers.activitytext">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:taskAffinity="gf.zy"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".TwoActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="ONETEXT_TWOACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".ThreeActivity">
<intent-filter>
<action android:name="ONETEXT_THREEACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
這是我的第一個應用OneText的Mainfest結構,里面創建了三個Activity,我們把第二個Activity的模式設定為singleTop,
每個Activity界面都只有一個顯示當前界面名稱的TextView和一個用來組跳轉的Button,所以應用OneText的功能就是從活動1跳轉到活動2,活動2繼續跳轉活動2,代碼就不給大家展示了,都能寫出來,
我們發現在我們跳轉到TwoActivity之后,點擊跳轉新的TwoActivity時候,他沒有回應,
為了作對比,我們再把TwoActivity設定為standard,看一看效果:
我們發現創建了很多的TwoActivity,
同時我們列印上task的Id(我沒有把所有周期方法都列印log):
發現他們全部都是來自一個Task,這個可以過,
應用場景:
開啟渠道多,適合多應用開啟呼叫的Activity:通過這種設定可以避免已經創建過的Activity被重復創建(多數通過動態設定使用,關于動態設定下面會詳細介紹)
3. 堆疊內復用模式singleTask:
與singleTop模式相似,只不過singleTop模式是只是針對堆疊頂的元素,而singleTask模式下,如果task堆疊記憶體在目標Activity實體,則:
- 將task內的對應Activity實體之上的所有Activity彈出堆疊,
- 將對應Activity置于堆疊頂,獲得焦點,
同樣我們也用代碼來實作一下這個程序:
還是剛才的那一坨代碼,只是我們修改一下Activity1的模式為singleTask,然后讓Activity2跳轉到Activity3,讓Activity3跳轉到Activity1:
在跳回MainActivity之后點擊back鍵發現直接退出參考了,這說明此時的MainActivity為task內的最后一個Activity,所以這個模式過,
應用場景:
程式主界面,我們肯定不希望主界面被多創建,而且在主界面退出的時候退出整個App是最好的設想,
耗費系統資源的Activity:對于那些及其耗費系統資源的Activity,我們可以考慮將其設為singleTask模式,減少資源耗費(在創建階段耗費資源的情況,個人理解-,+),
4.全域唯一模式singleInstance:
這是我們最后的一種啟動模式,也是我們最惡心的一種模式:在該模式下,我們會為目標Activity分配一個新的affinity,并創建一個新的Task堆疊,將目標Activity放入新的Task,并讓目標Activity獲得焦點,新的Task有且只有這一個Activity實體, 如果已經創建過目標Activity實體,則不會創建新的Task,而是將以前創建過的Activity喚醒(對應Task設為Foreground狀態)
我們為了看的更明確,這次不按照上圖的步驟設計程式了(沒錯,這幾張圖都不是我畫的-,+!),
我們先指定一下這次的程式:還是這三個Activity,這次Activity3設定為singleInstance,1和2默認(standard),
然后我們看一下這個效果:
說一下我們做了什么操作:
首先由1創建2,2創建3,然后又由3創建2,2創建3,3創建2,然后一直back,圖如下:
還請各位別嫌棄我-,+,圖雖然不好看,但是很生動形象,,,,具體說一下:這張圖對應著我們上面的程式流程,黃色的代表Background的Task,藍色的代表Foreground的Task,
我們發現back的時候會先把Foreground的Task中的Activity彈出,直到Task銷毀,然后才將Background的Task喚到前臺,所以最后將Activity3銷毀之后,會直接退出應用,
但是有沒有想過這樣會出現一個問題,什么問題我們直接看圖就好:
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/275003.html
標籤:Android
上一篇:求助,為什么編譯失敗 unresolved reference:role rolemanger找不到
下一篇:Swift 進階(七)方法、下標
