1. 程式人生 > >Android Activity啟動模式的設定

Android Activity啟動模式的設定

    Android為了使我們能夠打破預設的堆疊的先後出的模式,提供了兩個種方式:一種是在AndroidManifest.xml定義Activity時指定它的載入模式,另一種是在用Intent開啟一個Activity時,在Intent中加入標誌。如果兩種方式都用了,則後者的優先順序更高。
    兩種方式的差別在於,前者在於描述自己,向別的Acttivity等宣告你們如何來載入我;而後者則是動態的,指出我要求你(要啟動的Activity)如何來載入。本文的重點在於研究在AndroidManifest.xml中宣告載入模式。

    Android為我們定義了四種載入模式,分別是:standard、singleTop、singleTask和singleInstance。

    “拿來主義”——standard模式
     我們寫一段程式碼來測試一下standard載入模式,如下
     AndroidManifest.xml裡Activity的設定如下:

  1. <activityandroid:name=".Activity1"
  2. android:launchMode="standard"
  3. android:label="@string/app_name">
  4. <intent-filter>
  5. <actionandroid:name="android.intent.action.MAIN"/>
  6. <categoryandroid:name=
    "android.intent.category.LAUNCHER"/>
  7. </intent-filter>
  8. </activity>

     Activity1的程式碼如下:

  1. publicclass Activity1 extends Activity {  
  2. @Override
  3. publicvoid onCreate(Bundle savedInstanceState) {  
  4. super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.     }  
  7. /**當點選Activity時,啟動另一個Activity1*/
  8. @Override
  9. publicboolean onTouchEvent(MotionEvent event) {  
  10.         Intent intent = new Intent(this, Activity1.class);  
  11.         startActivity(intent);  
  12. returnsuper.onTouchEvent(event);  
  13.     }  

    然後我們啟動程式,開啟Activity1,然後點選Acitivity1,啟動另一個Activity1,然後再點選,再點選,再點選... 之後我們點返回鍵。
    發生了什麼事情?沒錯,我們按返回鍵返回一個又一個相同的Activity1。
    standard是Activity預設的載入模式,這種方式用一個詞來形容的話就是“拿來主義”。使用這種模式的Activity向所有使用它的Task宣告:“我這裡的這種Activity多著呢,誰需要的話我就給誰”。所以當一個Task請求載入這個Activity時,該Task直接例項化該Activity,並把它放到棧頂。
    因此我們的例子就出現了這樣的堆疊結構(假設我們點選了4次):

Activity1
Activity1
Activity1
Activity1
Activity1

    我們設想一個情形:我們要做一個圖片瀏覽器,第一個介面是圖片列表介面(假設為PictureListActivity),第二個介面是瀏覽該張圖片(假設為PictureViewActivity)。在PictureViewActivity中可以startActivity啟動瀏覽介面瀏覽上一張和下一張。
    如果每一張圖片的瀏覽啟動一個PictureViewActivity(當然你可能不是採用這種方式來瀏覽上一張和下一張,這裡只是舉個例子),如果採用standard模式的話,就會出現多個PictureViewActivity在堆疊中堆疊的情形。下面介紹的singleTop便可以解決這個問題。


    “拒絕堆疊”——singleTop模式

    我們將上面的例子稍加改動,AndroidManifest.xml中Acitivity1的launchMode改為singleTop,Activity1的程式碼修改如下:

  1. publicclass Activity1 extends Activity {  
  2. @Override
  3. publicvoid onCreate(Bundle savedInstanceState) {  
  4. super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6. //Activity1建立時顯示Toast
  7.         Toast.makeText(this"onCreate called!", Toast.LENGTH_SHORT).show();  
  8.     }  
  9. @Override
  10. protectedvoid onNewIntent(Intent intent) {  
  11.         setTitle("I am Activity1 too, but I called onNewIntent!");  
  12. super.onNewIntent(intent);  
  13.     }  
  14. //點選進入載入Activity1
  15. @Override
  16. publicboolean onTouchEvent(MotionEvent event) {  
  17.         Intent intent = new Intent(this, Activity1.class);  
  18.         startActivity(intent);  
  19. returnsuper.onTouchEvent(event);  
  20.     }  

    同樣,我們啟動程式,開啟Activity1,然後點選Acitivity1,啟動另一個Activity1,然後再點選,再點選,再點選... 之後我們點返回鍵。
    結果,Activity1第一次建立時,顯示一個Toast提示,onCreate被呼叫,當再次點選時,onCreate沒有被呼叫相反是進入了onNewIntent函式。當按返回鍵時,直接退出了該應用,可見,堆疊中只存在一個Acitivity1。
    可見,當activity被設定為singleTop的載入模式時,如果堆疊的頂部已經存在了該Activity,那麼,它便不會重新建立,而是呼叫onNewIntent。如果,該Activity存在,但不是在頂部,那麼該Activity依然要重新建立,請讀者自行驗證。
    因此singleTop模式的思想便是“拒絕堆疊”!
    以上說的兩種載入模式,Activity均可以例項化多次,而下面講的兩個載入模式就只可以例項化一次。

    “獨立門戶”——singleTask模式

    我們首先測試一下,在本應用內呼叫singleTask模式的Activity會出現什麼情況。

    我們寫兩個Activity(Activity1和Activity2),相互呼叫,其中Activity1為singleTask模式。AndroidManifest.xml如下:

  1. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  2. <activityandroid:name=".Activity1"
  3. android:launchMode="singleTask"
  4. android:label="@string/app_name">
  5. </activity>
  6. <activityandroid:name=".Activity2">
  7. <intent-filter>
  8. <actionandroid:name="android.intent.action.MAIN"/>
  9. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  10. </intent-filter>
  11. </activity>
  12. </application>

    兩個Activity的程式碼如下:

  1. /**Activity1的程式碼*/
  2. publicclass Activity1 extends Activity {  
  3. privatestaticfinal String TAG = "Activity1";  
  4. @Override
  5. publicvoid onCreate(Bundle savedInstanceState) {  
  6. super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main);  
  8.         Log.e(TAG, "Activity1 onCreate! HashCode=" + this.hashCode() + " TaskId=" + getTaskId());   
  9.     }  
  10. @Override
  11. protectedvoid onNewIntent(Intent intent) {  
  12.         Log.e(TAG, "Activity1 onNewIntent! HashCode="this.hashCode() + " TaskId=" + getTaskId());  
  13. super.onNewIntent(intent);  
  14.     }  
  15. @Override
  16. protectedvoid onDestroy() {  
  17.         Log.e("Activity1""Activity1 onDestroy! HashCode="+this.hashCode()+ "TaskId="+getTaskId());  
  18. super.onDestroy();  
  19.     }  
  20. /**點選進入Activity2*/
  21. @Override
  22. publicboolean onTouchEvent(MotionEvent event) {  
  23.         Intent intent = new Intent(this, Activity2.class);  
  24.         startActivity(intent);  
  25. returnsuper.onTouchEvent(event);  
  26.     }  
  1. /**Activity2的程式碼*/
  2. publicclass Activity2 extends Activity {  
  3. privatestaticfinal String TAG = "Activity2";  
  4. @Override
  5. protectedvoid onCreate(Bundle savedInstanceState) {  
  6. super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main2);  
  8.         Log.e(TAG, "Activity2 onCreated! HashCode=" + this.hashCode() + " TaskId="+getTaskId());  
  9.     }  
  10. @Override
  11. protectedvoid onDestroy() {  
  12.         Log.e(TAG, "Activity2 onDestroy! HashCode="+this.hashCode()+" TaskId="+getTaskId());  
  13. super.onDestroy();  
  14.     }  
  15. /**點選進入Activity1*/
  16. @Override
  17. publicboolean onTouchEvent(MotionEvent event) {  
  18.         Intent intent = new Intent(this, Activity1.class);  
  19.         startActivity(intent);  
  20. returnsuper.onTouchEvent(event);  
  21.     }  

    從程式碼中我們可以看出,每當兩個Activity建立、銷燬以及onNewIntent時,都會列印該Activity的HashCode和所在的Task id。

    我們的操作步驟是這樣的,開啟應用程式,預設啟動Activity2,點選Activity2,進入Activity1,再點選Activity1進入Activity2,再點選Activity2進入Activity1,然後按返回鍵,直到返回到Home。

    暈了吧,好寫個順序來形象的表示下:Activity2->Activity1(singleTask)->Activity2->Activity1(singleTask)。^_^

    進入Activity2,然後到Activity1,我們看Log資訊為:

    03-01 14:50:08.144: ERROR/Activity2(371): Activity2 onCreated! HashCode=1156067168 TaskId=7
    03-01 14:50:13.923: ERROR/Activity1(371): Activity1 onCreate! HashCode=1156107384 TaskId=7
    我們看到,當本應用啟動singleTask的Activity(Activity1)時,Activity1並沒用另外啟用一個任務。而是在原來的任務中建立了它。

    再從Activity1進入Activity2,然後再進入Activity1,這個過程,我們再看log資訊:

    03-01 14:53:50.823: ERROR/Activity2(371): Activity2 onCreated! HashCode=1156128904 TaskId=7
    03-01 14:53:58.154: ERROR/Activity1(371): Activity1 onNewIntent! HashCode=1156107384 TaskId=7
    03-01 14:53:58.394: ERROR/Activity2(371): Activity2 onDestroy! HashCode=1156128904 TaskId=7
    從這個Log資訊我們可以得到這個結論:當singleTask模式的Activity啟動時,如果發現在某個Task中已經存在,那麼它會先將該Activity(Activity1)上部的Activity(Activity2)銷燬,然後呼叫它(Activity1)的onNewIntent函式。

    我們下面來研究一下當singleTask的Activity被其他應用呼叫時的情況。

    為了使Activity1能夠被其他應用程式呼叫,我們在AndroidManifest.xml中加入action,如下:

  1. <activityandroid:name=".Activity1"
  2. android:launchMode="singleTask"
  3. android:label="@string/app_name">
  4. <intent-filter>
  5. <actionandroid:name="com.winuxxan.singleTask"/>
  6. <categoryandroid:name="android.intent.category.DEFAULT"/>
  7. </intent-filter>
  8. </activity>

    然後我們另外建立一個工程,建立一個Activity在初始化的時候啟動Activity1,程式碼如下:

  1. publicclass MyActivity extends Activity {  
  2. @Override
  3. publicvoid onCreate(Bundle savedInstanceState) {  
  4. super.onCreate(savedInstanceState);  
  5.         setContentView(R.layout.main);  
  6.         Log.e("MyActivity""TaskId=" + getTaskId());  
  7.         Intent intent = new Intent("com.winuxxan.singleTask");  
  8.         startActivity(intent);  
  9.     }  

    我們的操作方法是,MyActivity->Activity1->Activity2->Activity1,之後我們按Home鍵,然後再從Home重新進入MyActivity所在的應用。

    首先看MyActivity->Activity1這個過程,我們檢視Log資訊如下:

    03-01 15:04:25.784: ERROR/MyActivity(429): TaskId=9
    03-01 15:04:26.244: ERROR/Activity1(401): Activity1 onCreate! HashCode=1156107632 TaskId=10
    從這個Log資訊我們可以看出:當某個應用呼叫其他應用裡宣告的singleTask模式的Activity時,它會重新建立一個Task,然後將該Activity例項化並壓入堆疊。

    接著我們看Activity1和Activity2的相互切換,log資訊如下:

    03-01 15:04:47.524: ERROR/Activity2(401): Activity2 onCreated! HashCode=1156128104 TaskId=10
    03-01 15:04:50.674: ERROR/Activity1(401): Activity1 onNewIntent! HashCode=1156107632 TaskId=10
    03-01 15:04:50.994: ERROR/Activity2(401): Activity2 onDestroy! HashCode=1156128104 TaskId=10
    和我們所期望的那樣,如果Activity發現已經存在時,會銷燬其上的Activity,然後呼叫onNewIntent。

    之後,我們按Home鍵,返回桌面,然後,再次進入該應用,我們神奇的發現,我們進入的是MyActivity介面,taskId為10的所有Activity不知了蹤影!

    這是因為,該應用對應的task的id為9,所以,進入後之後MyActivity在該task中,所以最後顯示的是MyActivity。我的以上Activity1的程式碼實際上是不好的習慣,因為Activity1很可能會成為一個孤島,所以建議,如果該Activity的型別不是LAUNCHER,最好不要設為singleTask。

    那麼singleTask的這些特性有什麼用處?我們舉一個例子,瀏覽器就是一個singleTask的例子,啟動一個瀏覽器,在Android中是一個比較沉重的過程,它需要做很多初始化的工作,並且會有不小的記憶體開銷。如果有多個應用都來請求開啟網頁,那麼系統就不會不堪重負。因此,如果瀏覽器採用singleTask模式,如果有多個請求開啟網頁的請求,都會在一個Task中響應,這樣就會避免以上的情況。

    “孤獨寂寞”——singleInstance模式

我們現在來研究最後一個載入模式,singgleInstance,測試很簡單,我們只要在singleTask測試的例子中,將Activity1的模式改為singleInstance模式即可。

    我們首先進行同一應用內部的測試。

    首先Activity2->Activity1,觀察log資訊:

相關推薦

Android Activity啟動模式設定為SingleTask需要注意的地方

Android Activity啟動模式設定為SingleTask需要注意的地方 當Activity跳轉到啟動模式為SingleTask的Activity的時候,onRestart()不再回調,而是回撥 onNewInstance(Intent intent) 方法,其中引數可

Android Activity啟動模式設定

    Android為了使我們能夠打破預設的堆疊的先後出的模式,提供了兩個種方式:一種是在AndroidManifest.xml定義Activity時指定它的載入模式,另一種是在用Intent開啟一個Activity時,在Intent中加入標誌。如果兩種方式都用了,則後

Android Activity 啟動模式

.aspx art www 設置 instance ini cnblogs 順序 http Android啟動模式也就是Activity任務棧的運行模式:任務棧是用來存儲Activity的 在AndroidManifest.xml中的標簽

Android-Activity啟動模式(launchMode)

Activity啟動模式是非常重要的一塊內容,啟動模式直接關係到使用者的體驗 和 效能的提升等   Activity啟動模式分為四種:      如果不配置:launchMode,預設就是:standard 標準的   standard 標準的   singleTop 獨佔頂端   s

Android-Activity啟動模式-應用場景

在上一篇部落格中,Android-Activity啟動模式(launchMode),就介紹了Activity四種啟動模式的特點與使用等,但是到底什麼樣子的場景,去使用什麼樣子的啟動模式呢     Activity啟動模式分為四種:      如果不配置:launchMode,預設

android Activity 啟動模式 應用場景

棧的原理:先進後出,後進先出。所有操作都發生在棧頂。 首先介紹一下任務棧: (1)程式開啟時就建立了一個任務棧, 用於儲存當前程式的activity,所有的activity屬於一個任務棧。  (2)一個任務棧包含了一個activity的集合, 去有序的選擇哪一個activ

Android四大元件之Activity-啟動模式

1.Activity的啟動模式 當我們多次呼叫同一個Activity時,系統會重複建立多個例項並把它們一一放入任務棧中,這種方式顯然不符合我們的設計要求。所以Android在設計時就提供了四種啟動模式來解決此問題。 四種啟動模式分別如下: standard-標

Android-intent.addFlags-Activity啟動模式

之前寫的Android-Activity啟動模式(launchMode),Android-Activity啟動模式-應用場景,講解的都是在AndroidManifest.xml配置launchMode="四種啟動模式" Activity啟動模式分為四種:      如果不配置:launchMode,預設

[Android]當Activity啟動模式為singleTask時的生命週期

01-09 22:59:24.317 13063-13063/com.dongua.activitytest I/Activity1: onCreate: 01-09 22:59:24.319 130

Android歸納】Activity啟動模式

1、對於使用standard 模式的活動,系統不會在乎這個活動是否已經在返回棧中存在,每次啟動都會建立該活動的一個新的例項。 例如A啟動A,A再接著啟動A,A繼續啟動A,然後再分別出棧,如圖所示

Android入門——四大元件之Activity啟動模式

standrad singleTop singleTask singleInstance 在AndroidManifest.xml中通過中設定 <activity android:name=".MainActivity" android:l

Activity啟動模式的深入分析

啟用 ide net 啟動模式 soft adding class 任務 新的 網上關於Activity啟動模式的文章許多。可是看起來都千篇一律,看完之後我們都能理解這4種啟動模式。只是官方api對singleTask這個啟動模式解釋有些爭議,導致我事實

activity啟動模式之singleTop

att pear protect logs 實例 點擊 launch 操作 @override activity啟動模式之singleTop 一、簡介 二、設置方法 在AndroidManifest.xml中將要設置為singleTop啟動模式的頁面進行配置 <

關於Activity啟動模式の學習

開始去學習Android的一些基礎的知識,開始從新做人,一步步腳踏實地的去了解這個系統 今天看的是關於Activity的啟動模式的文章,記下來防止自己遺忘了: Activity的啟動模式一共有四種,分別為standard,singleTop(棧頂模式),singleTask(複用模式),si

Activity啟動模式之SingleInstance

啟動模式系列之:Activity啟動模式(Standrd和SingleTop) 啟動模式系列之:Activity啟動模式(SingleTask) 啟動模式系列之:Activity啟動模式(SingleInstance) 一,SingleInstance模式(單例項模式)

Android Activity 常用功能設定 全屏 橫豎屏等

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

探索Activity啟動模式

LifecycleActivity記為A,LifecycleActivity2記為B 一, Standard 略. 二, SingleTop 開啟App,啟動第一個Activity(A1),看到taskId == 2215 D/PRETTY_LOGGER: │ taskCou

Android:Ativity啟動模式LaunchMode

standard模式:預設的啟動模式,每啟動一個Activity就會在棧頂建立一個新的Activity例項 singleTop模式:在該模式下,如果要啟動的Activity位於棧頂,就會複用這個Activity,若不在棧頂,就重新建立一個新的Activity例項 singleTask模式:在該模式下,每次啟

Activity啟動模式

一,啟動模式分類: Standard(標準模式,預設) SingleTop(棧頂複用模式) SingleTask(棧內複用模式) SingleInstance(單例項模式) 通過AndroidManifest可配置Activity的LaunchMode.如果

Activity啟動模式圖文詳解:standard, singleTop, singleTask 以及 singleInstance

英文原文:Understand Android Activity's launchMode: standard, singleTop, singleTask and singleInstance  另外關於啟動模式還有篇很好的文章:Android中Activity四種啟動模式和taskAf