Activity啓動模式的理解

1、理解 Tasks and Back Stack(任務和後臺堆棧)

一個 App 對應一個 Task,該app 內的全部 activity 被安排在一個後臺堆棧裏。
多窗口模式下:一個windows下可能由多個 Task,系統爲每一個窗口單獨管理 Taskandroid

當啓動一個app時,系統爲其啓動一個Task。其它App進入後臺(每一個堆棧內的 acitivity處於中止狀態)。注意:若是後臺任務過多,系統會銷燬後臺活動以釋放內存,活動的狀態也會丟失。windows

2、管理任務

Android管理任務和後臺堆棧的方式,如上所述,經過將全部的活動連續地放在同一任務和「後進先出」的堆棧中,對於大多數應用程序來講是很是好的,而且沒必要擔憂您的活動與任務或它們如何退出有關。瀏覽器

可是,您可能會決定要中斷這種正常行爲:app

  • 也許您但願應用程序中的一個活動在啓動時 啓動一個新任務(而不是放在當前任務中);
  • 當啓動一個活動時,你想提出它的一個現有實例,而不是在堆棧的頂部建立一個新實例;
  • 當用戶離開任務時,除了根活動,,但願清除堆棧。

您能夠在<activity>清單元素中使用屬性,並在傳遞給startActivity()意圖中使用標誌。ide

在這方面,您可使用的主體 <activity> 屬性以下:性能

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

您可使用的主要意圖標誌是:this

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_SINGLE_TOP

3、定義啓動模式

Android中每一個界面都是一個Activity,切換界面操做實際上是多個不一樣Activity之間的實例化操做。在AndroidActivity的啓動模式決定了Activity的啓動運行方式。code

啓動模式容許您定義活動的新實例如何與當前任務關聯。你能夠用兩種方式定義不一樣的啓動模式:對象

  • 使用清單文件
    當在清單文件中聲明一個活動時,能夠指定活動在啓動時應如何與任務相關聯。
  • 使用 Intent flags
    當調用 startActivity() 時,能夠在乎圖中包含一個標誌,聲明新的活動如何(或是否)與當前任務相關聯。

所以,若是活動A啓動活動B,活動B能夠在其清單中定義它應該如何與當前任務相關聯(若是有的話),並且活動A也能夠請求活動B應該如何與當前任務相關聯。若是兩個活動都定義了活動B應該如何與任務相關聯,那麼活動A的請求(如意圖中定義的)將被授予活動B的請求(如清單中定義的)。事件

注意:一些啓動模式 在清單文件中可用 ,但不可用做爲意圖的標誌;一樣地,一些啓動模式做爲 flags 可用,但在清單中不能定義。

使用清單文件

Activity啓動模式設置:

<activity android:name=".MainActivity" android:launchMode="standard" />

Activity的四種啓動模式:

  1. standard(默認模式)
    系統在啓動的任務中建立活動的新實例並將意圖路由到該任務。
    該活動能夠被實例化屢次,每一個實例能夠屬於不一樣的任務,而且一個任務能夠具備多個實例。

  2. singleTop 若是活動的實例已經存在於當前任務的頂部,則系統經過調用其 onNewIntent()方法將意圖路由到該實例,而不是建立活動的新實例。

該活動能夠屢次實例化,每一個實例能夠屬於不一樣的任務,而且一個任務能夠有多個實例(但僅當在後臺堆棧頂部的活動不是活動的現有實例)。

  1. singleTask
    系統建立一個新任務並實例化新任務的根的活動。可是,若是活動的實例已經存在於單獨的任務中,則系統經過調用其 onNewIntent()方法將意圖路由到現有實例,而不是建立新實例。一次只能存在一個活動實例。

注意:雖然活動在一個新任務中啓動,但後退按鈕仍然將用戶返回到先前的活動。

  1. singleInstance
    singleTask 相同,只是系統沒有將任何其餘活動放入實例中。該活動始終是其任務的惟一成員,該活動啓動的任何活動在單獨的任務中打開。

在一個新棧中建立該Activity實例,並讓多個應用共享改棧中的該Activity實例。一旦改模式的Activity的實例存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例,其效果至關於多個應用程序共享一個應用,無論誰激活該Activity都會進入同一個應用中。

舉例

1.standard

public class MainActivity extends AppCompatActivity {

    TextView tv;

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

        tv = findViewById(R.id.textView);
        tv.setText(this.toString());

    }
   
    // 按鈕點擊事件
    public void launchStandard(View view) {
        startActivity(new Intent(this, MainActivity.class));
        tv.setText(this.toString());
    }
}

輸入圖片說明

由此可知,這種 Standard 模式是 每次都會建立新的Activity對象,當點擊返回按鈕時,他會將棧頂(當前Activity)消滅,而後跳到下一層。這種模式可能大多數狀況下不是咱們須要的,由於對系統性能的消耗過大。

2.singleTop
從上面的解釋中便可知道,在每次使用新的Activity時會自動檢測棧頂的當前Activity是不是須要引用的Activity,若是是則直接引用此Activity,而不會建立新的Activity。

<activity
            android:name=".SingleTopActivity"
            android:launchMode="singleTop"
            android:screenOrientation="portrait" />
public class MainActivity extends AppCompatActivity {

    TextView tv;

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

        tv = findViewById(R.id.textView);
        tv.setText(this.toString());

    }

    public void launchStandard(View view) {
        startActivity(new Intent(this, SingleTopActivity.class));
        tv.setText(this.toString());

    }
}
public class SingleTopActivity extends AppCompatActivity {

    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_top);
        tv = findViewById(R.id.textView);
        tv.setText(this.toString());
    }

   @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Toast.makeText(this,this.getClass().getSimpleName(),Toast.LENGTH_LONG).show();
    }

    public void launchSingleTop(View view) {
        startActivity(new Intent(this, SingleTopActivity.class));
        tv.setText(this.toString());
    }
}

輸入圖片說明

當在SingleTopActivity點擊 "啓動當前頁面按鈕" 時,不會建立新的對象,由於該Activity 處在棧頂,不會建立新的對象,可是會回調 onNewIntent() 方法。   

3.singleTask

此啓動模式和singleTop在名字上便可看出區別,即singleTop每次只檢測當前棧頂的Activity是不是咱們須要請求建立的,而singleTask則會檢測棧中所有的Activity對象,從上向下,若是檢測到是咱們所請求的則會消滅此Activity對象上面的對象,直接把檢測到的咱們須要的Activity置爲棧頂。

4.SingleInstance

此啓動模式和咱們使用的瀏覽器工做原理相似,咱們都知道在多個程序中訪問瀏覽器時,若是當前瀏覽器沒有打開,則打開瀏覽器,不然會在當前打開的瀏覽器中訪問。此模式會節省大量的系統資源,由於他能保證要請求的Activity對象在當前的棧中只存在一個。

上面即爲Android中的四種啓動模式,咱們在開發Android項目時會常用到,巧妙設置Activity的啓動模式會節省系統開銷和程序運行效率。

相關文章
相關標籤/搜索