天天看點

Android 5.0 Overview Screen--總覽畫面

 總覽畫面--overview screen,通常也指最近畫面,最近任務表,或者是最近app,它是一個顯示最近使用的activitys和tasks的系統級UI。使用者可以通過它進行應用導航,或者是選擇一個task 進行 resume,當然也可以将一個task或者是activity從該清單中移除

在Android L 中,一個activity裡面會包含多個事件,故一個Activity中會有多個檔案(document)以task的形式出現在overview screen中

如下圖:Google Drive 中多個 document 組成一個task呈現在 overview screen中

Android 5.0 Overview Screen--總覽畫面

通常來說,你應該允許系統決定你的task和activity是如何展現在overview screen 中的,而且你也不應該去修改這種行為。

但是你的app卻可以确定何時、怎樣出現在overview scree中。ActivityManager.AppTask 類能夠讓使用者自己管理task,當然我們也可以在manifest檔案中利用 Intent 類的flag 标簽來描述一個activity是何時添加和從overview scren 中移除

在 Overview Screen 中添加 Task

使用 Intent 類的 Flag 标簽在 overview screen 中添加task能狗提供關于一個document 在overview screen 中打開或者是重新打開的更大控制權

當你使用 <activity>屬性,你則可以選擇永遠在一個新 task 中打開一個document 或者是為該document reuse 一個已經存在的task

使用 Intent flag 添加一個task

當你調用ActivityManager.AppTask類中的 startActivity() 方法時,目前的activity就會建立一個新的document,并給該document 傳遞一個 Intent 。 如果在給Intent 中添加 addFlags() 方法,并傳遞 flag:FLAG_ACTIVITY_NEW_DOCUMENT ,系統就會将建立的Activity 作為一個新的task顯示在 overview screen中

注意:标簽 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 在 Android 5.0 中已經棄用,替換為:FLAG_ACTIVITY_NEW_DOCUMENT

當你建立一個新的document的時候,如果在 Intent 中添加了 FLAG_ACTIVITY_MULTIPLE_TASK 标簽,那麼系統将會永遠建立一個新的task,并把目标Activity設定為該task 的 root,這樣就允許同一個 document 在多個task中打開。

具體執行個體如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">public void createNewDocument(View view) {
      final Intent newDocumentIntent = newDocumentIntent();
      if (useMultipleTasks) {
          newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
      }
      startActivity(newDocumentIntent);
  }

  private Intent newDocumentIntent() {
      boolean useMultipleTasks = mCheckbox.isChecked();
      final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
      newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
      newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
      return newDocumentIntent;
  }

  private static int incrementAndGet() {
      Log.d(TAG, "incrementAndGet(): " + mDocumentCounter);
      return mDocumentCounter++;
  }
}</span>
           

 注意:被啟動的Activity 如果被設定了FLAG_ACTIVITY_NEW_DOCUMENT  标簽,那麼它必須在mainfest 檔案中設定啟動屬性為: android:launchMode="standard"

當主activity要啟動一個新的activity的時候,系統就會搜尋目前存在的task中哪個Intent 的 action name 和 Intent data 與主activity 傳遞過來的 Intent 比對。關于Intent 是如何解析的,可以參考部落格 Android Intent Filter 簡析

如果沒有找到比對的task,或者是 主activity 的Intent 中包含FLAG_ACTIVITY_MULTIPLE_TASK 标簽,那麼系統就會建立一個task,并把該activity作為root activity

如果系統找到了一個比對的task,則會将該task放到棧頂并傳遞一個Intent,新的activity 就會擷取到這個Intent 并在overview screen 中建立一個新的document  

執行個體如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_document);
    mDocumentCount = getIntent()
            .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0);
    mDocumentCounterTextView = (TextView) findViewById(
            R.id.hello_new_document_text_view);
    setDocumentCounterText(R.string.hello_new_document_counter);
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity
    is reused to create a new document.
     */
    setDocumentCounterText(R.string.reusing_document_counter);
}</span>
           

使用 activit 屬性添加task

在一個activity在mainfest檔案中添加 屬性:android:documentLaunchMode 時,該activity被啟動時永遠會建立一個新的task。該屬性有4個值,使用者在應用中打開一個document時會有不同的效果:

intoExisting: activity 會為該document請求一個已經存在的task,這與 設定FLAG_ACTIVITY_NEW_DOCUMENT 且不設定 FLAG_ACTIVITY_MULTIPLE_TASK 有相同的效果

always: activity 會為該document建立一個新的task,即使該document已經被打開了,這與設定 FLAG_ACTIVITY_NEW_DOCUMENT 且設定 FLAG_ACTIVITY_MULTIPLE_TASK 有相同的效果

none:activity 不會為 document 建立新的task,該app被設定為 single task 的模式,它會重新調用使用者喚醒的所有activity中的最近的一個

never:activity 不會為document建立一個新的task,設定這個值複寫了 FLAG_ACTIVITY_NEW_DOCUMENT 和 FLAG_ACTIVITY_MULTIPLE_TASK 标簽。如果其中一個标簽被設定,并且overview screen 顯示該app為 single task 模式。 則該activity 會重新調用使用者最近喚醒的activity

注意: none 或 nerver 使用時,activity必須設定為 launchMode=”standard” ,如果該屬性沒有設定,documentLaunchMode=”none” 屬性就會被使用

移除Tasks

預設情況下,當一個activity 被 finished 的時候,它的document tasks 就會被自動從 overview screen 中移除,然而,你也可以通過設定 <activity>的 android:excludeFromRecents 屬性為true 來在overview screen 中移除 task

通過在 标簽中設定 android:maxRecents 屬性為一個 integer 類型的值,可以設定你的app在overview screen 中可以包含的task的最小值,預設是16,預設最大值是50,記憶體較低的可能為25.當overview screen中包含的一個app 的task到達最大值的時候,最近最少使用的task就會被移出overview screen

使用 AppTask 類 去移除 tasks

在一個你在overview screen中建立了一個task的activity中。你可以通過調用finishAndRemoveTask() 函數描述何時移除task 并結束所有的activitys 之間的關聯

執行個體如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">public void onRemoveFromRecents(View view) {
    // The document is no longer needed; remove its task.
    finishAndRemoveTask();
}</span>
           

注意:使用finishAndRemoveTask() 函數的方法複寫了 FLAG_ACTIVITY_RETAIN_IN_RECENTS Tag,如下面所述

保留 finished 的 tasks

如果想要在overview screen 中保留一個task,即使它所屬的activity 已經 finish 了,可以在要啟動該activity的Intent中添加flag:FLAG_ACTIVITY_RETAIN_IN_RECENTS

執行個體如下:

<span style="font-family:Microsoft YaHei;font-size:14px;">private Intent newDocumentIntent() {
    final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
    newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
      android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
    newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
    return newDocumentIntent;
}</span>
           

同樣的,在mainfest檔案的<activity> 标簽中設定屬性: android:autoRemoveFromRecents 為false也有相同效果