Activity 使用總結(jié)

Activity使用詳解

LaunchMode

standard

在AndroidManifest中聲明

<activity android:name=".lm_standard.ActivityA"
            android:launchMode="standard"/>
            
// java
public class ActivityA extends Activity {

    private static final String TAG = "lm_standard_ActivityA";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_standard_a);

        Log.d(TAG, "onCreate " + this + " tasksId -> " + getTaskId());
    }

    public void startA(View view) {

        Log.d(TAG, "startA from " + this);

        Intent activity = new Intent(this, ActivityA.class);
        startActivity(activity);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        Log.d(TAG, "onDestroy " + this);
    }
}

進入ActivityA后暴备,連續(xù)觸發(fā)了2次startA,然后陸續(xù)返回3次:

04-26 17:49:03.065 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onCreate com.seven.www.activityusage.lm_standard.ActivityA@c2ba76d tasksId -> 280
04-26 17:49:04.225 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: startA from com.seven.www.activityusage.lm_standard.ActivityA@c2ba76d
04-26 17:49:04.337 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onCreate com.seven.www.activityusage.lm_standard.ActivityA@9990b77 tasksId -> 280
04-26 17:49:05.534 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: startA from com.seven.www.activityusage.lm_standard.ActivityA@9990b77
04-26 17:49:05.650 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onCreate com.seven.www.activityusage.lm_standard.ActivityA@286e87b tasksId -> 280

04-26 17:49:11.312 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onDestroy com.seven.www.activityusage.lm_standard.ActivityA@286e87b
04-26 17:49:13.033 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onDestroy com.seven.www.activityusage.lm_standard.ActivityA@9990b77
04-26 17:49:15.450 25218-25218/com.seven.www.activityusage D/lm_standard_ActivityA: onDestroy com.seven.www.activityusage.lm_standard.ActivityA@c2ba76d

可以看出每次都會啟動一個全新的Activity,并且放在同一個task里面衣撬,返回也是按照創(chuàng)建順序的倒敘逐個銷毀景馁。

singleTop

添加了兩個Activity, 分別為ActivityB ActivityC,其中ActivityB launchMode為singleTop, ActivityC 的LaunchMode為standard.

// ActivityB
public class ActivityB extends Activity {

    private static final String TAG = "lm_singleTop";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singletop_b);

        Log.d(TAG, "onCreate " + this + "  taskId -> " + getTaskId());
    }

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

        Log.d(TAG, "onNewIntent " + this + " taskId -> " + getTaskId());
    }

    public void startB(View view) {
        Log.d(TAG, "startB");
        Intent activity = new Intent(this, ActivityB.class);
        startActivity(activity);
    }

    public void startC(View view) {
        Log.d(TAG, "startC");
        Intent activity = new Intent(this, ActivityC.class);
        startActivity(activity);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy " + this);
    }
}
// ActivityC
public class ActivityC extends Activity {

    private static final String TAG = "lm_singleTop";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singletop_c);

        Log.d(TAG, "onCreate " + this + "  taskId -> " + getTaskId());
    }

    public void startB(View view) {
        Log.d(TAG, "startB");
        Intent activity = new Intent(this, ActivityB.class);
        startActivity(activity);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy " + this);
    }
}

進入ActivityB后觸發(fā)了一次startB斥难,再點擊了一下返回:

04-27 09:10:04.838 25444-25444/com.seven.www.activityusage D/lm_singleTop: onCreate com.seven.www.activityusage.lm_singletop.ActivityB@9a6d920  taskId -> 285
04-27 09:10:08.832 25444-25444/com.seven.www.activityusage D/lm_singleTop: startB
04-27 09:10:08.847 25444-25444/com.seven.www.activityusage D/lm_singleTop: onNewIntent com.seven.www.activityusage.lm_singletop.ActivityB@9a6d920 taskId -> 285

04-27 09:10:15.019 25444-25444/com.seven.www.activityusage D/lm_singleTop: onDestroy com.seven.www.activityusage.lm_singletop.ActivityB@9a6d920 taskId -> 284


進入ActivityB依次觸發(fā)startC -> startB枝嘶,再點擊3次返回:

04-27 09:11:42.972 25444-25444/com.seven.www.activityusage D/lm_singleTop: onCreate com.seven.www.activityusage.lm_singletop.ActivityB@78d9444  taskId -> 285
04-27 09:11:44.321 25444-25444/com.seven.www.activityusage D/lm_singleTop: startC
04-27 09:11:44.408 25444-25444/com.seven.www.activityusage D/lm_singleTop: onCreate com.seven.www.activityusage.lm_singletop.ActivityC@4d57c36  taskId -> 285
04-27 09:11:46.010 25444-25444/com.seven.www.activityusage D/lm_singleTop: startB
04-27 09:11:46.100 25444-25444/com.seven.www.activityusage D/lm_singleTop: onCreate com.seven.www.activityusage.lm_singletop.ActivityB@33043b3  taskId -> 285
04-27 09:12:16.328 25444-25444/com.seven.www.activityusage D/lm_singleTop: onDestroy com.seven.www.activityusage.lm_singletop.ActivityB@33043b3
04-27 09:12:22.529 25444-25444/com.seven.www.activityusage D/lm_singleTop: onDestroy com.seven.www.activityusage.lm_singletop.ActivityC@4d57c36
04-27 09:12:24.426 25444-25444/com.seven.www.activityusage D/lm_singleTop: onDestroy com.seven.www.activityusage.lm_singletop.ActivityB@78d9444

可以看出,如果ActivityB處于棧頂哑诊,那么startB不會新建一個Activity群扶,而是觸發(fā)棧頂Activity的onNewIntent方法。如果ActivityB不處于棧頂镀裤,那么startB的結(jié)果
和standard的模式是一致的竞阐。

singleTask

添加2個Activity,ActivityD和ActivityE暑劝,D為singleTask骆莹,E為standard:

// ActivityD
public class ActivityD extends Activity {

    private static final String TAG = "lm_singleTask";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_singletask_d);

        Log.d(TAG, "onCreate " + this + " taskId -> " + getTaskId());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "onNewIntent " + this + " taskId -> " + getTaskId());
    }

    public void startE(View view) {
        Intent activity = new Intent(this, ActivityE.class);
        startActivity(activity);
    }

    public void startD(View view) {
        Intent activity = new Intent(this, ActivityD.class);
        startActivity(activity);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy " + this);
    }
}
// ActivityE
public class ActivityE extends ActivityD {
}

進入D,觸發(fā)2次startE铃岔,再觸發(fā)startD:

04-27 09:43:07.850 26815-26815/com.seven.www.activityusage D/lm_singleTask: onCreate com.seven.www.activityusage.lm_singletask.ActivityD@7dd0052 taskId -> 287
04-27 09:43:27.325 26815-26815/com.seven.www.activityusage D/lm_singleTask: onCreate com.seven.www.activityusage.lm_singletask.ActivityE@b6edeac taskId -> 287
04-27 09:43:28.259 26815-26815/com.seven.www.activityusage D/lm_singleTask: onCreate com.seven.www.activityusage.lm_singletask.ActivityE@5194736 taskId -> 287
04-27 09:43:34.044 26815-26815/com.seven.www.activityusage D/lm_singleTask: onDestroy com.seven.www.activityusage.lm_singletask.ActivityE@b6edeac
04-27 09:43:34.069 26815-26815/com.seven.www.activityusage D/lm_singleTask: onNewIntent com.seven.www.activityusage.lm_singletask.ActivityD@7dd0052 taskId -> 287
04-27 09:43:34.417 26815-26815/com.seven.www.activityusage D/lm_singleTask: onDestroy com.seven.www.activityusage.lm_singletask.ActivityE@5194736

可以看出汪疮,當啟動D時峭火,如果D已經(jīng)在棧內(nèi),那么不會重新創(chuàng)建D智嚷,而是觸發(fā)D的onNewIntent卖丸,并且全部銷毀處于D頭上的其他Activity。如果D處于棧頂盏道,則退化成singleTop模式稍浆。

singleInstance

添加連個Activity,分別為ActivityF和ActivityG猜嘱,F(xiàn)為singleInstance衅枫,G為standard

// ActivityF
public class ActivityF extends Activity {

    private static final String TAG = "lm_singleInstance";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_singleinstance_f);
        Log.d(TAG, "onCreate " + this + " taskId -> " + getTaskId());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "onNewIntent " + this + " taskId -> " + getTaskId());
    }

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

    public void startF(View view) {
        Log.d(TAG, "startF");
        Intent activity = new Intent(this, ActivityF.class);
        startActivity(activity);
    }

    public void startG(View view) {
        Log.d(TAG, "startG");
        Intent activity = new Intent(this, ActivityG.class);
        startActivity(activity);
    }
}
// ActivityG
public class ActivityG extends ActivityF {
}

進入G,觸發(fā)startF -> startG -> startF -> startG朗伶,然后陸續(xù)點擊返回

04-27 10:52:34.069 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onCreate com.seven.www.activityusage.lm_singleinstance.ActivityG@d2e261f taskId -> 313
04-27 10:52:35.310 29785-29785/com.seven.www.activityusage D/lm_singleInstance: startF
04-27 10:52:35.413 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onCreate com.seven.www.activityusage.lm_singleinstance.ActivityF@372e491 taskId -> 314
04-27 10:52:46.427 29785-29785/com.seven.www.activityusage D/lm_singleInstance: startG
04-27 10:52:46.502 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onCreate com.seven.www.activityusage.lm_singleinstance.ActivityG@233f873 taskId -> 313
04-27 10:54:17.462 29785-29785/com.seven.www.activityusage D/lm_singleInstance: startF
04-27 10:54:17.494 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onNewIntent com.seven.www.activityusage.lm_singleinstance.ActivityF@372e491 taskId -> 314
04-27 10:56:53.108 29785-29785/com.seven.www.activityusage D/lm_singleInstance: startG
04-27 10:56:53.188 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onCreate com.seven.www.activityusage.lm_singleinstance.ActivityG@9e4a99a taskId -> 313

04-27 10:58:05.029 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onDestroy com.seven.www.activityusage.lm_singleinstance.ActivityG@9e4a99a
04-27 10:58:06.689 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onDestroy com.seven.www.activityusage.lm_singleinstance.ActivityG@233f873
04-27 10:58:10.425 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onDestroy com.seven.www.activityusage.lm_singleinstance.ActivityG@d2e261f
04-27 10:58:25.168 29785-29785/com.seven.www.activityusage D/lm_singleInstance: onDestroy com.seven.www.activityusage.lm_singleinstance.ActivityF@372e491

可以看出弦撩,啟動F時,如果F不存在论皆,那么創(chuàng)建新的task益楼,將F加入新的task中;如果F存在点晴,那么就觸發(fā)F的onNewIntent感凤。從F啟動G時,系統(tǒng)切換到G默認的任務(wù)粒督,再重新創(chuàng)建G陪竿。
因此可以知道,singleTask的Activity獨占一個task屠橄,即一個task如果含有一個singleInstance的Activity族跛,那么就不能再存在其他Activity了。

FLAG_ACTIVITY_XXX 標識 和 taskAffinity

默認情況下锐墙,每個Activity的taskAffinity都是包名庸蔼,Android的最近任務(wù)是按照taskAffinity來進行分組的,不同的task如果taskAffinity相同贮匕,那么將放在同一個卡片組里面。也就是說花枫,最近任務(wù)不是顯示每一個任務(wù)刻盐,而是按照不同的taskAffinity顯示其靠前的任務(wù)的最頂層Activity

假設(shè)存在3個task:

task1: A -> B -> C (taskAffinity1)

task2: D -> E (taskAffinity2)

task3: G (taskAffinity2)

因為只存在2個taskAffinity,所以在最近任務(wù)里面只有2個卡片劳翰, 卡片1顯示的 C敦锌,卡片2則需要根據(jù)實際情況而定:

  1. 如果 task2在task stack中比task3靠前,那么顯示的就是E
  2. 反之 顯示的是G

查看那個task靠前佳簸,可以通過adb shell dumpsys activity activities查看.

注意:如果我們在最近任務(wù)里面選擇了某個task乙墙,那么系統(tǒng)僅僅是將該task調(diào)度到最前面颖变,但是和這個task具有相同的taskAffinity的task被放到了最近任務(wù)和系統(tǒng)桌面的下面,也就是說听想,我們永遠無法通過返回按鍵或者最近任務(wù)按鍵 回到那些沒顯示在最近任務(wù)里的task了腥刹。因此一般來說,設(shè)置taskAffinity都不是什么好事情汉买。盡量避免衔峰。

FLAG_ACTIVITY_NEW_TASK

如果目標Activity已經(jīng)在一個task(不能是默認task)中運行了,并且蛙粘,這次startActivity查找到的任務(wù)就是該task垫卤,那么這次操作僅僅是將該任務(wù)切換到前臺,不會創(chuàng)建新的Activity出牧。
如果目標Activity不存在:

1) 如果目標Activity設(shè)置了taskAffinity穴肘,那么系統(tǒng)將創(chuàng)建一個全新的task,然后創(chuàng)建該Activity放在task的里面舔痕。
2) 如果沒有設(shè)置taskAffinity评抚,那么系統(tǒng)不會創(chuàng)建task,而是創(chuàng)建該Activity放在默認task里面赵讯。(如果設(shè)置了singleInstance盈咳,那么還是會創(chuàng)建一個新task)

這個FLAG需要和taskAffinity配合使用。

在Android7.0以前边翼,如果使用Service/Application/Broadcast/類型的Context

FLAG_ACTIVITY_CLEAR_TOP

如果目標Activity在task中存在鱼响,那么銷毀目標Activity上面的Activty,并觸發(fā)onNewIntent.
如果不存在组底,那么創(chuàng)建一個新的丈积,加入task棧頂。

這個FLAG和 launchMode:singleTask類似

FLAG_ACTIVITY_SINGLE_TOP

這個FLAG和 launchMode:singleTop類似

FLAG_ACTIVITY_NO_HISTORY

離開Activity后該Activity即銷毀债鸡,該Activity的onActivityResult也不會觸發(fā)江滨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厌均,隨后出現(xiàn)的幾起案子唬滑,更是在濱河造成了極大的恐慌,老刑警劉巖棺弊,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晶密,死亡現(xiàn)場離奇詭異,居然都是意外死亡模她,警方通過查閱死者的電腦和手機稻艰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侈净,“玉大人尊勿,你說我怎么就攤上這事僧凤。” “怎么了元扔?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵躯保,是天一觀的道長。 經(jīng)常有香客問我摇展,道長吻氧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任咏连,我火速辦了婚禮盯孙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祟滴。我一直安慰自己振惰,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布垄懂。 她就那樣靜靜地躺著骑晶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪草慧。 梳的紋絲不亂的頭發(fā)上桶蛔,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音漫谷,去河邊找鬼仔雷。 笑死,一個胖子當著我的面吹牛舔示,可吹牛的內(nèi)容都是我干的碟婆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼惕稻,長吁一口氣:“原來是場噩夢啊……” “哼竖共!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起俺祠,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤公给,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜘渣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妓布,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年宋梧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狰挡。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡捂龄,死狀恐怖释涛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倦沧,我是刑警寧澤唇撬,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站展融,受9級特大地震影響窖认,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜告希,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一扑浸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燕偶,春花似錦喝噪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伯诬,卻和暖如春晚唇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗似。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工哩陕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人桥言。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓萌踱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親号阿。 傳聞我的和親對象是個殘疾皇子并鸵,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 【Android Activity】 什么是 Activity? 四大組件之一,通常一個用戶交互界面對應(yīng)一個 ac...
    Rtia閱讀 3,796評論 3 18
  • 個人總結(jié): 一個應(yīng)用程序只有一個任務(wù)棧(Stack)枯夜; 一個應(yīng)用程序可以有多個Task(一個Task表現(xiàn)于回退棧弯汰,...
    畫十閱讀 1,685評論 0 3
  • 任務(wù)和返回棧 應(yīng)用通常包含多個Activity。每個 Activity 均應(yīng)圍繞用戶可以執(zhí)行的特定操作設(shè)計湖雹,并且能...
    xinlingzhiyi閱讀 672評論 0 6
  • 一咏闪、概述 Activity 作為與用戶交互的一個窗口,是使用非常頻繁的一個基本組件摔吏。Android系統(tǒng)是通過Act...
    三也視界閱讀 2,225評論 3 11
  • 進入3月初春鸽嫂,恰到好處的天氣纵装,不熱不冷。暖洋洋的太陽据某,讓人想外出的沖動橡娄。 旅游業(yè)也進入了忙碌的季節(jié),收客多多癣籽,所以...
    豹子伢閱讀 286評論 0 1