Android每個Application都是由若干個四大組件組成的负懦。每個頁面都是一個Activity,當(dāng)需要打開相應(yīng)頁面(Activity)時系統(tǒng)會創(chuàng)建他們的實(shí)例并把他們一一放入棧中進(jìn)行管理锌奴。任務(wù)棧是一種“后進(jìn)先出”的棧結(jié)構(gòu),通過back鍵庶溶,我們可以發(fā)現(xiàn)這些Activity會一一出棧(PS:不斷返回上一頁)秦踪。如果每次啟動Activity都創(chuàng)建一個實(shí)例,會不會很浪費(fèi)資源爬范。能不能進(jìn)行Activity的復(fù)用呢?Android系統(tǒng)在設(shè)計就考慮到這個問題弱匪,所以提供了同步的Activity啟動模式青瀑,在不同條件下進(jìn)行Activity的復(fù)用。其中都包括:Standard萧诫、SingleTop斥难、SingleTask、SingleInstance帘饶。
(PS:本篇文章的實(shí)驗(yàn)數(shù)據(jù)都基于Android7.0)
在講述Activity啟動模式之前我們先了解一些基礎(chǔ)概念:
Application 是組件的集合哑诊。
Process 操作系統(tǒng)調(diào)度的單位。
Task是指在執(zhí)行特定作業(yè)時與用戶交互的一系列 Activity及刻。Task以棧的形式管理Activity集合镀裤。
- 一個應(yīng)用中可以有多個Task
- 不同應(yīng)用的Activity可以放在同一個Task中進(jìn)行管理
- 一個應(yīng)用中可以有多個Process
- Task可以運(yùn)行在不同進(jìn)程
standard
標(biāo)準(zhǔn)啟動模式,也是activity的默認(rèn)啟動模式缴饭。在這種模式下啟動的activity可以被多次實(shí)例化暑劝,即在同一個任務(wù)中可以存在多個activity的實(shí)例,每個實(shí)例都會處理一個Intent對象颗搂。
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".AActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".BActivity"
android:launchMode="standard"/>
</application>
- Logcat輸出
3459-3459 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6384
3459-3459 D/$$$AActivity: onClickBtn: AActivity start BActivity
3459-3459 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6384
3459-3459 D/$$$BActivity: onClickBtn: BActivity start AActivity
3459-3459 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6384
3459-3459 D/$$$AActivity: onClickBtn: AActivity start BActivity
3459-3459 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6384
- 當(dāng)前任務(wù)棧
Running activities (most recent first):
TaskRecord{3efeab #6384 A=com.tzx.launchmodel U=0 StackId=1 sz=4}
Run #4: ActivityRecord{18878b0 u0 com.tzx.launchmodel/.BActivity t6384}
Run #3: ActivityRecord{5a7f957 u0 com.tzx.launchmodel/.AActivity t6384}
Run #2: ActivityRecord{559bd5f u0 com.tzx.launchmodel/.BActivity t6384}
Run #1: ActivityRecord{facb908 u0 com.tzx.launchmodel/.AActivity t6384}
singleTop
啟動的activity的實(shí)例已經(jīng)存在于任務(wù)桟的桟頂担猛,那么再啟動這個Activity時,不會創(chuàng)建新的實(shí)例丢氢,而是重用位于棧頂?shù)哪莻€實(shí)例傅联,并且會調(diào)用該實(shí)例的onNewIntent()方法將Intent對象傳遞到這個實(shí)例中。
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".AActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".BActivity"
android:launchMode="singleTop"/>
</application>
- Logcat輸出
14450-14450 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6386
14450-14450 D/$$$AActivity: onClickBtn: AActivity start BActivity
14450-14450 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6386
14450-14450 D/$$$BActivity: onClickBtn: BActivity start AActivity
14450-14450 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6386
14450-14450 D/$$$AActivity: onClickBtn: AActivity start BActivity
14450-14450 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6386
14450-14450 D/$$$BActivity: onClickBtn: BActivity start BActivity
14450-14450 D/$$$BActivity: onNewIntent()
14450-14450 D/$$$BActivity: onClickBtn: BActivity start BActivity
14450-14450 D/$$$BActivity: onNewIntent()
- 當(dāng)前任務(wù)棧
Running activities (most recent first):
TaskRecord{fba1a37 #6386 A=com.tzx.launchmodel U=0 StackId=1 sz=4}
Run #5: ActivityRecord{9609e73 u0 com.tzx.launchmodel/.BActivity t6386}
Run #4: ActivityRecord{50fff56 u0 com.tzx.launchmodel/.AActivity t6386}
Run #3: ActivityRecord{1c403e9 u0 com.tzx.launchmodel/.BActivity t6386}
Run #2: ActivityRecord{3c41ba4 u0 com.tzx.launchmodel/.AActivity t6386}
singleTask
啟動模式為singleTask疚察,那么系統(tǒng)總會在一個新任務(wù)的最底部(root)啟動這個activity蒸走,并且被這個activity啟動的其他activity會和該activity同時存在于這個新任務(wù)中。如果系統(tǒng)中已經(jīng)存在這樣的一個activity則會重用這個實(shí)例稍浆,并且調(diào)用他的onNewIntent()方法载碌。即猜嘱,這樣的一個activity在系統(tǒng)中只會存在一個實(shí)例。
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".AActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".BActivity"
android:launchMode="singleTask"/>
<activity android:name=".CActivity"
android:process=":remote"/>
</application>
- Logcat輸出
19684-19684 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6394
19684-19684 D/$$$AActivity: onClickBtn: AActivity start BActivity
19684-19684 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6394
19684-19684 D/$$$BActivity: onClickBtn: BActivity start AActivity
19684-19684 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6394
19684-19684 D/$$$AActivity: onClickBtn: AActivity start CActivity
19921-19921 D/$$$CActivity: onCreate: currentActivityName:CActivity currentTaskID:6394
19921-19921 D/$$$CActivity: onClickBtn: CActivity start AActivity
19684-19684 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6394
19684-19684 D/$$$AActivity: onClickBtn: AActivity start BActivity
19684-19684 D/$$$BActivity: onNewIntent()
19684-19684 D/$$$BActivity: onClickBtn: BActivity start BActivity
19684-19684 D/$$$BActivity: onNewIntent()
- 當(dāng)前任務(wù)棧
Running activities (most recent first):
TaskRecord{8e8fb09 #6394 A=com.tzx.launchmodel U=0 StackId=1 sz=2}
Run #7: ActivityRecord{7489fc u0 com.tzx.launchmodel/.BActivity t6394}
Run #6: ActivityRecord{9a5d10e u0 com.tzx.launchmodel/.AActivity t6394}
singleInstance
總是在新的任務(wù)中開啟嫁艇,并且這個新的任務(wù)中有且只有這一個實(shí)例朗伶。
- AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".AActivity"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".BActivity"
android:launchMode="singleInstance"/>
<activity android:name=".CActivity"
android:process=":remote"/>
</application>
- Logcat輸出
25016-25016 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6396
25016-25016 D/$$$AActivity: onClickBtn: AActivity start BActivity
25016-25016 D/$$$BActivity: onCreate: currentActivityName:BActivity currentTaskID:6397
25016-25016 D/$$$BActivity: onClickBtn: BActivity start AActivity
25016-25016 D/$$$AActivity: onCreate: currentActivityName:AActivity currentTaskID:6396
25016-25016 D/$$$AActivity: onClickBtn: AActivity start CActivity
26003-26003 D/$$$CActivity: onCreate: currentActivityName:CActivity currentTaskID:6396
26003-26003 D/$$$CActivity: onClickBtn: CActivity start BActivity
25016-25016 D/$$$BActivity: onNewIntent()
- 當(dāng)前任務(wù)棧
Running activities (most recent first):
TaskRecord{d5934c9 #6397 A=com.tzx.launchmodel U=0 StackId=1 sz=1}
Run #9: ActivityRecord{986e7ce u0 com.tzx.launchmodel/.BActivity t6397}
TaskRecord{f282078 #6396 A=com.tzx.launchmodel U=0 StackId=1 sz=3}
Run #8: ActivityRecord{d2c75de u0 com.tzx.launchmodel/.CActivity t6396}
Run #7: ActivityRecord{2d3a2eb u0 com.tzx.launchmodel/.AActivity t6396}
Run #6: ActivityRecord{2ca9351 u0 com.tzx.launchmodel/.AActivity t6396}
本文敘述性的文字非常少,主要通過其代碼和其運(yùn)行結(jié)果然后得出我們需要的結(jié)論步咪。每一種設(shè)計模式我都畫了一副圖论皆,可以使大家理解記憶深刻。
Activity啟動模式到這里就結(jié)束了么猾漫,然而并沒有点晴。之前看過其他類似文章或者書籍的同學(xué)都知道還有Activity的Flags和 android:taskAffinity
標(biāo)簽對Activity的啟動有影響。這些內(nèi)容我們放在下一張深入理解Activity啟動模式之大結(jié)局中講述悯周,有興趣的同學(xué)可以點(diǎn)擊閱讀\~粒督!
文章到這里就全部講述完啦,若有其他需要交流的可以留言哦~禽翼!~屠橄!