Tasks and Back Stack
(任務和後臺堆棧)一個 App
對應一個 Task
,該app
內的全部 activity
被安排在一個後臺堆棧裏。
多窗口模式下:一個windows
下可能由多個 Task
,系統爲每一個窗口單獨管理 Task
。android
當啓動一個app
時,系統爲其啓動一個Task
。其它App
進入後臺(每一個堆棧內的 acitivity
處於中止狀態)。注意:若是後臺任務過多,系統會銷燬後臺活動以釋放內存,活動的狀態也會丟失。windows
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
在Android
中每一個界面都是一個Activity
,切換界面操做實際上是多個不一樣Activity
之間的實例化操做。在Android
中Activity
的啓動模式決定了Activity
的啓動運行方式。code
啓動模式容許您定義活動的新實例如何與當前任務關聯。你能夠用兩種方式定義不一樣的啓動模式:對象
Intent flags
startActivity()
時,能夠在乎圖中包含一個標誌,聲明新的活動如何(或是否)與當前任務相關聯。所以,若是活動A啓動活動B,活動B能夠在其清單中定義它應該如何與當前任務相關聯(若是有的話),並且活動A也能夠請求活動B應該如何與當前任務相關聯。若是兩個活動都定義了活動B應該如何與任務相關聯,那麼活動A的請求(如意圖中定義的)將被授予活動B的請求(如清單中定義的)。事件
注意:一些啓動模式 在清單文件中可用 ,但不可用做爲意圖的標誌;一樣地,一些啓動模式做爲 flags
可用,但在清單中不能定義。
Activity
啓動模式設置:
<activity android:name=".MainActivity" android:launchMode="standard" />
Activity
的四種啓動模式:
standard
(默認模式)
系統在啓動的任務中建立活動的新實例並將意圖路由到該任務。
該活動能夠被實例化屢次,每一個實例能夠屬於不一樣的任務,而且一個任務能夠具備多個實例。
singleTop
若是活動的實例已經存在於當前任務的頂部,則系統經過調用其 onNewIntent()
方法將意圖路由到該實例,而不是建立活動的新實例。
該活動能夠屢次實例化,每一個實例能夠屬於不一樣的任務,而且一個任務能夠有多個實例(但僅當在後臺堆棧頂部的活動不是活動的現有實例)。
singleTask
onNewIntent()
方法將意圖路由到現有實例,而不是建立新實例。一次只能存在一個活動實例。注意:雖然活動在一個新任務中啓動,但後退按鈕仍然將用戶返回到先前的活動。
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的啓動模式會節省系統開銷和程序運行效率。