Activity 必知必會(huì)

1. Activity 的生命周期

1.1 分類

在講解生命周期的方法之前,先放上這張官方的圖:

image

這張圖片講述了 Activity 的回調(diào)的方法,下表分類講解這些方法的作用。

生命周期方法 作用
onCreate 表示 Activity 正在被創(chuàng)建
onRestart 表示 Activity 正在重新啟動(dòng)
onStart 表示 Activity 正在被啟動(dòng)
onResume 表示 Activity 已經(jīng)可見
onPause 表示 Activity 正在停止
onStop 表示 Activity 即將停止
onDestroy 表示 Activity 即將被銷毀

1.2 各種情況下生命周期的回調(diào)

以下總結(jié)一下各種情況下,生命周期中的回調(diào)情況(表中的 A,B 代表的是兩個(gè) Activity):

情況 回調(diào)
第一次啟動(dòng) onCreate() -> onStart() -> onResume()
從 A 跳轉(zhuǎn)到不透明的 B A_onPause() -> B_onCreate() -> B_onStart() -> B_onResume() -> A_onStop()
從 A 跳轉(zhuǎn)到透明的 B A_onPause() -> B_onCreate() -> B_onStart() -> B_onResume()
從不透明的 B 再次回到 A B_onPause() -> A_onRestart() -> A_onStart() -> A_onResume() -> B_onStop()
從透明的 B 再次回到 A B_onPause() -> A_onResume() -> B_onStop() -> B_onDestroy()
用戶按 home 鍵 onPause() -> onStop()
按 home 鍵回后回到應(yīng)用 onRestart() -> onStart() -> onResume()
用戶按 back 鍵回退 onPause() -> onStop() -> onDestroy()

1.3 onSaveInstanceState() 與 onRestoreInstanceState()

這兩個(gè)方法只有在應(yīng)用遇到意外情況下才會(huì)觸發(fā)。可以用于保存一些臨時(shí)性的數(shù)據(jù)。

1.3.1 觸發(fā)場(chǎng)景

onSaveInstanceState():

  1. 橫豎屏切換
  2. 按下電源鍵
  3. 按下菜單鍵
  4. 切換到別的 Activity
  5. ....

onRestoreInstanceState():

  1. 橫豎屏切換
  2. 切換語言
  3. ....

2. Activity 之間的跳轉(zhuǎn)

2.1 相關(guān)API

2.1.1 startActivity()

怎么用:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);

使用這個(gè)方法就可以跳轉(zhuǎn)到 SecondActivity

2.1.2 startActivityforResult()

怎么用:

MainActivity.java:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);

這里第二個(gè)參數(shù)是一個(gè) requestCode,這個(gè)參數(shù)會(huì)在 onActivityResult 回調(diào)回來。

SecondActivity.java:

setResult(2);
finish();

當(dāng) SecondActivity finish 后會(huì)回調(diào) MainActivity 中的 onActivityResult 方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.e("chan", "==================onActivityResult main= " + requestCode + " " + resultCode);
}

打印結(jié)果:

E/chan: ==================onActivityResult main= 1 2

當(dāng)然你也可以不調(diào)用 setResult() 方法,這時(shí)回調(diào)過來的 resultCode 就是 0。

2.2 顯式啟動(dòng)

顯示啟動(dòng)分類:

  1. 直接在 Intent 構(gòu)造方法啟動(dòng):
Intent intent = new Intent(this, SecondActivity.class);
  1. setComponent:
ComponentName componentName = new ComponentName(this, SecondActivity.class);
Intent intent = new Intent();
intent.setComponent(componentName);
  1. setClass / setClassName:
Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);
intent.setClassName(this, "com.example.administrator.myapplication.SecondActivity");

2.3 隱式啟動(dòng)

隱式啟動(dòng)就是要在該 Activity 中設(shè)置 IntentFilter 屬性,只要啟用的 Intent 匹配 IntentFilter 的條件就可以啟動(dòng)相應(yīng)的 Activity。

要理解隱式啟動(dòng)就必須要理解 IntentFilter 是如何使用的

2.3.1 IntentFilter 的使用

IntentFilter 有三個(gè)標(biāo)簽分別是:

  1. action
  2. category
  3. data

這三個(gè)標(biāo)簽都有對(duì)應(yīng)的匹配規(guī)則,下面會(huì)說到。這里來說下使用 IntentFilter 要注意的地方

  1. 一個(gè) Activity 中可以有多個(gè) intent-filter
  2. 一個(gè) intent-filter 同時(shí)可以有多個(gè) action,category,data
  3. 一個(gè) Intent 只要能匹配任何一組 intent-filter 即可啟動(dòng)對(duì)應(yīng) Activity
  4. 新建的 Activity 必須加上以下這句:
<category android:name="android.intent.category.DEFAULT"/>

否則就會(huì)出現(xiàn)如下錯(cuò)誤:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.chan1 }

2.3.2 action 的匹配規(guī)則

action 的匹配規(guī)則就是只要滿足其中一個(gè) action 就可以啟動(dòng)成功。

在 Manifest 定義一個(gè) SecondActivity:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.chan" />
        <action android:name="com.chan2" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
    <action android:name="com.chan3" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

MainActivity:

Intent intent = new Intent();
intent.setAction("com.chan2");
startActivity(intent);

這樣就可以啟動(dòng) SecondActivity,要注意的是 action 是區(qū)分大小寫的。

2.3.3 category 匹配規(guī)則

category 在代碼設(shè)置如下:

intent.addCategory("com.zede");

這句可以添加也可以不添加,因?yàn)榇a默認(rèn)會(huì)為我們匹配 “android.intent. category.DEFAULT”。

2.3.4 data 匹配規(guī)則

data 主要是由 URI 和 mimeType 組成的。URI 的結(jié)構(gòu)如下:

<scheme> :// <host> : <port> [<path>|<pathPrefix>|<pathPattern>]

這些值在 Manifest 文件中可以定義,語法如下:

<data android:scheme="string"
      android:host="string"
      android:port="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:mimeType="string" />

以下用一個(gè)例子來說明:

Manifest:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data
            android:host="zede"
            android:port="1010"
            android:scheme="chan" />
    </intent-filter>
</activity>

MainActivity:

Intent intent = new Intent();
intent.setData(Uri.parse("chan://zede:1010"));
startActivity(intent);

通過這個(gè)方法就可以跳轉(zhuǎn)到 SecondActivity。

我們也可以創(chuàng)建一個(gè) html 文件,來實(shí)現(xiàn)跳轉(zhuǎn) SecondActivity。

test.html:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<a href="chan://zede:1010">跳轉(zhuǎn)至SecondActivity</a>
</body>
</html>

使用手機(jī)瀏覽器打開這個(gè) html 文件,點(diǎn)擊這個(gè)超鏈接也可以跳轉(zhuǎn)到 SecondActivity。

通過這個(gè)鏈接也可以傳輸數(shù)據(jù)到 SecondActivity,代碼如下:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<a href="chan://zede:1010/mypath?user=admin&psd=123456">跳轉(zhuǎn)至SecondActivity</a>
</body>
</html>

在 SecondActivity 接收數(shù)據(jù):

Intent intent = getIntent();
Uri uri = intent.getData();

Log.e("chan", "==================getScheme= " + intent.getScheme());
Log.e("chan", "==================getHost= " + uri.getHost());
Log.e("chan", "==================getPort= " + uri.getPort());
Log.e("chan", "==================getPath= " + uri.getPath());

Log.e("chan", "==================getQuery= " + uri.getQuery());

Set < String > names = uri.getQueryParameterNames();

Iterator < String > iterator = names.iterator();
while (iterator.hasNext()) {
    String key = iterator.next();
    uri.getQueryParameter(key);
    Log.e("chan", "==================getQueryParameter= " + uri.getQueryParameter(key));
}

打印結(jié)果:

07-19 10:47:54.969 19201-19201/com.example.administrator.myapplication E/chan: ==================getScheme= chan
07-19 10:47:54.970 19201-19201/com.example.administrator.myapplication E/chan: ==================getHost= zede
    ==================getPort= 1010
    ==================getPath= /mypath
    ==================getQuery= user=admin&psd=123456
    ==================getQueryParameter= admin
    ==================getQueryParameter= 123456

另外還需要注意另一個(gè)屬性:android:mimeType,這個(gè)屬性就是說要傳遞什么類型的數(shù)據(jù),通常有 text/plain 或 image/jpeg。

可以通過以下代碼來啟動(dòng) Activity:

intent.setType("text/plain");

不過需要注意的是,如果同時(shí)設(shè)置了 URI 和 mimeType 的話就必須使用如下代碼才可以跳轉(zhuǎn):

intent.setDataAndType(Uri.parse("chan://zede:1010"), "text/plain");

因?yàn)槿绻褂?setData() 或者 setType() 的話,分別會(huì)將相應(yīng) type 和 data 置為 null。

3. Activity的啟動(dòng)模式

3.1 分類:

啟動(dòng)模式 作用
standard 每次啟動(dòng)都會(huì)重新創(chuàng)建一個(gè) Activity
singleTop 如果該棧頂上有所要啟動(dòng)的 Activity,那么就不會(huì)重新創(chuàng)建該 Activity,并會(huì)回調(diào) onNewIntent()
singleTask 如果棧內(nèi)已經(jīng)有所要啟動(dòng)的 Activity 就不會(huì)被創(chuàng)建,同時(shí)也會(huì)調(diào)用 onNewIntent()
singleInstance 創(chuàng)建該 Activity 系統(tǒng)會(huì)創(chuàng)建一個(gè)新的任務(wù)棧

這里重點(diǎn)說下 singleTask。

3.2 singleTask 分析

singleTask 叫做棧內(nèi)復(fù)用模式,這個(gè)啟動(dòng)模式的啟動(dòng)邏輯如下圖:

singleTask 邏輯

相信看了上面這個(gè)圖,大家也清楚 singleTask 的邏輯了,但是這個(gè)模式還有幾個(gè)需要注意的地方。

3.2.1 taskAffinity

前面提到 A 想要的任務(wù)棧,那什么是 A 想要的任務(wù)棧呢?這就提到一個(gè)屬性 taskAffinity,以下詳細(xì)介紹這個(gè)屬性。

3.2.1.1 作用

標(biāo)識(shí)一個(gè) Activity 所需要的任務(wù)棧的名字。如果不設(shè)置這個(gè)屬性值,默認(rèn)值是應(yīng)用的包名。

3.2.1.2 taskAffinity 與 singleTask 配對(duì)使用

如果啟動(dòng)了設(shè)置了這兩個(gè)屬性的 Activity,這個(gè) Activity 就會(huì)在 taskAffinity 設(shè)置的任務(wù)棧中,下面用代碼來驗(yàn)證下:

創(chuàng)建 SecondActvitiy,在 Mnifest 文件設(shè)置 SecondActvitiy,代碼如下:

<activity android:name=".SecondActivity"
    android:taskAffinity="com.chan"
    android:launchMode="singleTask" />

現(xiàn)在使用 MainActivity 啟動(dòng) SecondActvitiy,這里的代碼就不展示了,我們直接看看結(jié)果,在終端輸入以下命令:

adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'

這個(gè)命令可以查看正在運(yùn)行的 Activity,結(jié)果如下:

Running activities (most recent first):
    TaskRecord{762a040 #63 A=com.chan U=0 StackId=1 sz=1}
    Run #1: ActivityRecord{3881f68 u0 com.example.activitydemo/.SecondActivity t63}
    TaskRecord{351eb79 #62 A=com.example.activitydemo U=0 StackId=1 sz=1}

從打印結(jié)果可以看出, MainActivity 和 SecondActivity 運(yùn)行在不同的任務(wù)棧中。

3.2.1.3 taskAffinity 和 allowTaskReparenting 配對(duì)使用

allowTaskReparenting 這個(gè)屬性直接解釋的話,可能很多人都會(huì)聽得懵逼,下面直接使用例子來解釋:

現(xiàn)在創(chuàng)建兩個(gè)應(yīng)用,一個(gè)應(yīng)用的包名為:com.example.activitydemo,以下成為應(yīng)用 A。另一個(gè)應(yīng)用的包名為:com.example.hellodemo,以下稱為應(yīng)用 B。

在應(yīng)用 A 的 MainActivtiy 中添加如下代碼:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.start1).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        Intent intent=new Intent();
        intent.setClassName("com.example.hellodemo", "com.example.hellodemo.HelloActivity");
        startActivity(intent);
        }
    });

}

應(yīng)用 B 中創(chuàng)建 HelloActivity,并在 Manifest 文件中設(shè)置 HelloActivity 的 allowTaskReparenting 為 true,代碼如下:

<activity android:name=".HelloActivity"
    android:exported="true"
    android:allowTaskReparenting="true" />

然后根據(jù)以下步驟操作:

  1. 現(xiàn)在先運(yùn)行應(yīng)用 B,然后退出
  2. 再運(yùn)行應(yīng)用 A,點(diǎn)擊按鈕啟動(dòng)
  3. 按 home 鍵,回到主界面
  4. 啟動(dòng)應(yīng)用 B

完成第二步的時(shí)候,在終端看下任務(wù)棧的情況:

Running activities (most recent first):
    TaskRecord{5d54c1c #85 A=com.example.activitydemo U=0 StackId=1 sz=2}
    Run #1: ActivityRecord{ff0b8e u0 com.example.hellodemo/.HelloActivity t85}
    Run #0: ActivityRecord{95ee35c u0 com.example.activitydemo/.MainActivity t85}

可以看出 HelloActivity 運(yùn)行在應(yīng)用 A 的任務(wù)棧中。

完成第四步后,再看下任務(wù)棧:

Running activities (most recent first):
    TaskRecord{74c894d #86 A=com.example.hellodemo U=0 StackId=1 sz=2}
        Run #1: ActivityRecord{ff0b8e u0 com.example.hellodemo/.HelloActivity t86}
    TaskRecord{5d54c1c #85 A=com.example.activitydemo U=0 StackId=1 sz=1}
        Run #0: ActivityRecord{95ee35c u0 com.example.activitydemo/.MainActivity t85}

從結(jié)果可以看到,HelloActivity 從應(yīng)用 A 的任務(wù)棧移動(dòng)到應(yīng)用 B 的任務(wù)棧。

現(xiàn)在再修改下 HelloActivity 的 taskAffinity 屬性,代碼如下:

<activity android:name=".HelloActivity"
    android:exported="true"
    android:allowTaskReparenting="true"
    android:taskAffinity="com.chan"/>

重新根據(jù)以上步驟操作,操作完畢后看下任務(wù)棧信息:

Running activities (most recent first):
    TaskRecord{50264fe #90 A=com.example.hellodemo U=0 StackId=1 sz=1}
    Run #2: ActivityRecord{bc77713 u0 com.example.hellodemo/.MainActivity t90}
    TaskRecord{41abf9e #89 A=com.example.activitydemo U=0 StackId=1 sz=2}
    Run #1: ActivityRecord{2d0b7bb u0 com.example.hellodemo/.HelloActivity t89}
    Run #0: ActivityRecord{8b57551 u0 com.example.activitydemo/.MainActivity t89}

可以看出 HelloActivity 并沒有移動(dòng)到應(yīng)用 B 的主任務(wù)棧中,因?yàn)檫@并不是 HelloActivity 想要的任務(wù)棧。

繼續(xù)修改 HelloActivity 配置屬性,增加 singleTask 屬性:

<activity android:name=".HelloActivity"
    android:exported="true"
    android:allowTaskReparenting="true"
    android:taskAffinity="com.chan"
    android:launchMode="singleTask"/>

繼續(xù)操作,任務(wù)棧結(jié)果如下:

Running activities (most recent first):
    TaskRecord{775e709 #95 A=com.example.hellodemo U=0 StackId=1 sz=1}
        Run #2: ActivityRecord{757bb47 u0 com.example.hellodemo/.MainActivity t95}
    TaskRecord{aa75b2 #94 A=com.chan U=0 StackId=1 sz=1}
        Run #1: ActivityRecord{76e2133 u0 com.example.hellodemo/.HelloActivity t94}
    TaskRecord{21c8903 #93 A=com.example.activitydemo U=0 StackId=1 sz=1}
        Run #0: ActivityRecord{be84df4 u0 com.example.activitydemo/.MainActivity t93}

可以看出與沒有增加 singleTask 屬性的結(jié)果是一樣的,其實(shí) allowTaskReparenting 這個(gè)屬性的最主要作用就是將這個(gè) Activity 轉(zhuǎn)移到它所屬的任務(wù)棧中,例如一個(gè)短信應(yīng)用收到一條帶網(wǎng)絡(luò)鏈接的短信,點(diǎn)擊鏈接會(huì)跳轉(zhuǎn)到瀏覽器中,這時(shí)候如果 allowTaskReparenting 設(shè)置為 true 的話,打開瀏覽器應(yīng)用就會(huì)直接顯示剛才打開的網(wǎng)頁(yè)頁(yè)面,而打開短信應(yīng)用后這個(gè)瀏覽器界面就會(huì)消失。

3.3 指定啟動(dòng)模式的方式

指定啟動(dòng)模式的方式有兩種,一種是在 AndroidMenifest 文件設(shè)置 launchMode 屬性,另一種就是在 Intent 當(dāng)中設(shè)置標(biāo)志位。第二種方式的優(yōu)先級(jí)會(huì)比第一種的要高,如果兩種都設(shè)置了會(huì)以第二種方式為準(zhǔn)。我們來驗(yàn)證一下:

在 MainActivity 設(shè)置如下代碼:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.start1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, SecondActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            }
        });

    }

SecondActivity 在 AndroidMenifest 設(shè)置如下:

        <activity android:name=".SecondActivity"
            android:taskAffinity="com.chan" />

這里我并沒有設(shè)置 SecondActivity 為 sigleTask,來驗(yàn)證下啟動(dòng) SecondActivity 是否會(huì)開啟一個(gè)新的任務(wù)棧。

運(yùn)行后,任務(wù)棧的結(jié)果為:

    Running activities (most recent first):
      TaskRecord{148d7c5 #143 A=com.chan U=0 StackId=1 sz=1}
        Run #2: ActivityRecord{de59b2d u0 com.example.activitydemo/.SecondActivity t143}
      TaskRecord{520151a #142 A=com.example.activitydemo U=0 StackId=1 sz=1}
        Run #1: ActivityRecord{d80bfc1 u0 com.example.activitydemo/.MainActivity t142}

從結(jié)果可以看出,是開啟了一個(gè)新的任務(wù)棧的,也證明了第二種方式的優(yōu)先級(jí)比較高

3.4 onNewIntent 回調(diào)時(shí)機(jī)

啟動(dòng) singleTask 的 Activity 的時(shí)候會(huì)回調(diào) onNewIntent() 方法,但是并不是所有情況都這樣,總結(jié)如下圖:

onNewIntent 回調(diào)時(shí)機(jī)

以下使用代碼來驗(yàn)證一下這四種情況:

3.4.1 不存在 A 所需的任務(wù)棧

代碼如下:

MainActivity.java:

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.start1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }
        });

    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("chan", "MainActivity=======================onNewIntent");
    }


}

SecondActivity.java:

public class SecondActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        findViewById(R.id.start2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
            }
        });

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("chan", "SecondActivity=======================onNewIntent");
    }
}

清單文件中將 SecondActivity 設(shè)置為 singleTask,taskAffinity 屬性設(shè)置一個(gè)非該程序包名的值,代碼如下:

        <activity android:name=".SecondActivity"
            android:taskAffinity="com.onnewintent"
            android:launchMode="singleTask" />

以上代碼的結(jié)果并沒有打印任何東西,證明這樣并不會(huì)回調(diào) onNewIntent()。

3.4.2 存在 A 所需的任務(wù)棧

這種情況還要分兩種子情況,一種就是 A 不在棧中,另一種 A 不在棧中。

3.4.2.1 A 不在棧中

還是用回上面的例子的代碼,添加一個(gè) ThridActivity,ThridActivity 在清單文件描述如下:

        <activity android:name=".ThirdActivity"
            android:taskAffinity="com.onnewintent"
            android:launchMode="singleTask" />

點(diǎn)擊 SecondActivity 跳轉(zhuǎn)按鈕后同樣也不會(huì)有任何打印,證明并不會(huì)回調(diào) onNewIntent()。

3.4.2.2 A 在棧中

這種情況也會(huì)分兩種子情況,一種就是 A 在棧頂,另一種就是 A 不在棧頂。

3.4.2.2.1 A 在棧頂

同樣也是使用上面的例子,修改 ThirdActivity,代碼如下:

public class ThirdActivity extends AppCompatActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        findViewById(R.id.start3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(ThirdActivity.this, ThirdActivity.class));
            }
        });

    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("chan", "ThirdActivity=======================onNewIntent");
    }


}

到 ThirdActivity 時(shí),ThirdActivity 已經(jīng)是在棧頂了,這時(shí)候點(diǎn)擊按鈕再次啟動(dòng) ThirdActivity,打印結(jié)果如下:

chan    : ThirdActivity=======================onNewIntent

可以發(fā)現(xiàn)這種情況會(huì)回調(diào) ThirdActivity 的 onNewIntent。

3.4.2.2.2 A 不在在棧頂

同樣改動(dòng) ThirdActivity,這次啟動(dòng)的是 SecondActivity。具體代碼就不寫了,打印結(jié)果如下:

chan    : SecondActivity=======================onNewIntent

可以發(fā)現(xiàn)這種情況會(huì)回調(diào) SecondActivity 的 onNewIntent。

3.5 Activity 中的 Flags

3.5.1 FLAG_ACTIVITY_NEW_TASK

與啟動(dòng)模式 singleTask 的作用一樣,必須設(shè)置 taskAffinity

3.5.2 FLAG_ACTIVITY_SINGLE_TOP

與啟動(dòng)模式 singleTop 的作用一樣

3.5.3 FLAG_ACTIVITY_CLEAR_TOP

從名字就可以看出這個(gè)標(biāo)志的作用就是如果這個(gè) Activity 頂部有別的 Activity 的話,那么就會(huì)它頂部的 Activity 全部出棧,如果這個(gè) Activity 的啟動(dòng)模式為 standard 的話,就會(huì)將之前的 Activity 出棧,并且創(chuàng)建一個(gè)新的 Activity,如果不是的話就會(huì)調(diào)用 onNewIntent 方法。

3.5.4 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

不能在查看歷史 Activity 中查看到此 Activity

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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