編輯:關於Android編程
在我們寫應用的時候,常常涉及多個activity組件之間的跳轉。比如說某個資訊的頁面中,點擊下一篇資訊跳轉相同的頁面,只有頁面的數據不一樣。一般情況下我不會注意launchMode 這個屬性,只會使用默認的,這樣會產生大量重復的activity。那是因為之前不了解,所以特此研究學習。
基本上我們可以直接指定一個launchMode屬性在AndroidManifest.xml 文件中
存在4中類型的launchMode
這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。
activity設置為這個模式的行為是一個新的活動,每一個意圖發送,將總是被創建的工作分開。想象一下,如果有10的意圖去寫郵件,應該有10個活動的開展為每一個單獨的意圖。因此,有可能是一個無限數量的這種活動在一個設備啟動。
2.1 5.0 版本之前
這種activity將被創建,並放置在堆棧的頂部,在同一個task,發送一個Intent。
下面的一個圖片顯示當我們將一個圖像分享到一個標准的activity時會發生什麼。它將被堆疊在同一個任務中,雖然他們是從不同的應用程序。
這是你將在任務管理器中看到的。(可能有點奇怪)
如果我們換到另一個應用程序,然後再切換回Gallery,我們仍將看到頂上畫廊的任務launchMode標准的地方。因此,如果我們需要做任何與Gallery相關的操作,我們必須完成當前activity的事情或者關閉當前的activity,才可以回到原來的地方。
2.2 5.0版本之後
如果這些活動都來自同一個應用程序,它能夠像5.0之前一樣,堆疊的任務
但是在某些情況下,我們發送的Intent 來自不同的intent,新的task將被創建,新創建的activity將被放置在下面的根activity中。
下面是我們重任務管理器中看到的和5.0之前是有區別的
這是因為任務管理系統的改進Lollipop使它更有意義。Lollipop,你可以切換回畫廊,因為它們是不同的任務。你可以發射另一個意圖,一個新的任務將被創建,以服務一個與前一個相同的意圖。
2.3 應用場景舉例
這種activity的一個例子是一個組成電子郵件activity或社交網絡的狀態張貼activity。如果你考慮一個可以單獨工作的活動,為一個單獨的意圖服務。
舉例引用:
AlarmClock uses standard. The user can launch multiple instances of this activity and these instances can be part of any task and anywhere in the activity stack. As a fairly simple application it doesn’t really demand tight control of its activity
鬧鐘的使用 standard。用戶可以啟動此activity的多個實例,這些實例可以是任何任務的一部分,也可以是活動堆棧中的任何地方的一部分。作為一個相當簡單的應用,它並不真的需要它的activity的嚴格控制
singleTop模式。它的作用幾乎和standard一樣。唯一不同的是,如果已經存在在棧頂在對方的任務一個同類型的活動實例,不會有任何新的activity創造,而是被發送到一個存在的activity實例通過onNewIntent() 方法的意圖,即會重用該實例調用當前activity的onNewIntent() 方法。
在singleTop模式,對於新的Intent,你要負責onCreate() 和 onNewIntent() 來控制使它適用於所有的情況。
3.1 應用場景舉例
這個模式的一個示例用例是一個搜索功能。我們想創造一個搜索框,它會帶你到一個SearchActivity看到搜索結果。為了更好的用戶體驗,我們通常總是把一個搜索框,在搜索結果頁面以及讓用戶做另一個搜索無壓回。
現在想象一下,如果我們總是推出服務新的搜索結果的新searchactivity,10次搜索將產生10個新activity。這將是非常奇怪的,當你按下回來,因為你必須要10次,通過這些搜索結果activity,以獲得回你的根activity。相反,如果在棧頂 searchactivity,我們最好送一個Intent的一個存在的activity實例,讓它更新搜索結果。現在只會有一個searchactivity放在棧頂,你可以簡單地按下按鈕就回一次回到以前的活動。現在有更多的意義。
反正singleTop 作用相同的任務棧。如果你期望一個Intent被發送到一個存在的活動放置在任何其他任務的頂部,我必須讓你失望,說它不工作。如果Intent是從另一個應用程序發送到singleTop activity,新的activity將推出在同一方面作為standard launchMode。
注意:5.0之前:放在對方的任務,5.0以及之後(Lollipop):一個新的任務被創建。
舉例引用:
BrowserBookmarksPage uses singleTop. While there can be multiple instances of this activity, if there is already one at the top of the task’s activity stack it will be reused and onNewIntent() will be called. This way you only have to hit back once to return to the browser if the bookmarks activity is started multiple times.
浏覽書簽頁面使用singleTop。雖然有可能是這一活動的多個實例,如果已經有一個在任務棧頂的活動將被重用和onnewintent()將被調用。這樣,你只需要返回一次返回到浏覽器,如果書簽activity是開始多次。
這種模式和 standard singleTop完全不同。采用singleTask launchMode 的activity是允許在系統中只有一個實例(又名Singleton)。如果系統中有一個存在的活動實例,整個任務將實例將被移動到頂部,Intent將通過onnewintent()方法交付。否則,新的activity將被創建並放置在適當的任務中。
4.1 在同一個應用中
如果沒有在系統中還存在singleTask活動實例,新一將要建立簡單的放在棧頂在同一個任務。
但如果有一個存在的singleTask activity實例放在上面,會自動地破壞(以恰當的方式 生命周期觸發)其他的activity,讓該實例出現在棧頂。同時,一個Intent是通過的onnewintent()方法送到singleTask activity。
在用戶體驗上沒有一個很好的感覺,但它是這樣設計的…
The system creates a new task and instantiates the activity at the root of the new task.
注意:系統創建一個新任務並實例化活動新任務的根。
但從實驗中,它似乎不工作。單一任務活動仍棧頂上的任務的活動堆棧。從中我們可以看到什麼dumpsys活動命令顯示。
如果你想讓一個活動就像描述singleTask文檔:創建一個新的任務,把活動作為一根活動。你需要指定的taskAffinity屬性為singleTask這樣的活動。
下面是啟動SingleTaskActivity 的結果示例
考慮是否使用taskAffinity的行為,這是你的工作。
4.2 與另一個應用合作
一旦一個 Intent 是從另一個應用程序發送,並且沒有在系統中創建的任何活動實例,新的任務將創建一個新創建的活動作為一個根活動。
除非有一個應用程序,是一個擁有調用singleTask activity存在的任務,創造了新的活動會放在上面。
如果有任何任務存在的活動實例,整個任務將被移動到頂部和每個單獨的activity在singleTask activity上的將會被銷毀按照正常的生命周期。如果按下後退按鈕,用戶必須在返回到調用方任務之前通過堆棧中的活動進行。即先關閉圖中task#1 中的activity,再回到task#2.
4.3 應用場景示例
這種模式的一個示例用例是任何一個入口點活動例如電子郵件客戶端的收件箱頁面或社交網絡的時間軸。無論如何,你必須明智地使用這個模式,在這種模式下活動可能會被破壞。
BrowserActivity uses singleTask. There is only one browser activity at a time and it doesn’t become part tasks that send it intents to open web pages. While it might return to whatever most recently launched it when you hit back it is actually fixed at the bottom of its own task activity stack. It will share its task with activities that it launches like bookmarks
browseractivity使用singleTask。只有一個浏覽器的活動的時間,它不成為一部分的任務,把它試圖打開網頁。雖然它可能會返回到任何最近推出的它,當你回擊它實際上是固定在其自己的任務活動棧的底部。它將分享它的任務與活動,它推出像書簽.
這種模式是相當接近singleTask,單個activity實例可以存在於系統中。不同的是任務舉行這次活動,只能有一個活動。如果這種活動調用另一個活動,一個新的任務將被自動創建,以放置新的活動。同樣,如果singleInstance活動被被調用,新的任務將會被創建放置這個activity。
無論如何,結果是相當奇怪的。從dumpsys提供的信息,它在系統中有兩個任務,但只有一個出現在任務管理器中最新的一個決定,移動到頂部。因此,雖然有一個任務,仍然在後台工作,但我們不能切換到前台。根本沒有任何意義。
這是singleInstance活動被調用同時一個activity已經存在在task 中。
但是在任務管理器中看不到新的task
由於這項任務可能只有一個活動,我們無法切換回任務# 1了。這樣做的唯一方法是重新啟動的應用程序,但看來singleInstance任務將被隱藏在後台。
簡單地分配taskAffinity屬性到singleInstance活動使任務管理多個任務。
這樣將看到被隱藏的task
5.1 應用場景示例
AlarmAlert uses singleInstance. Only one alert activity at a time and it is always its own task. Anything it launches (if anything) becomes part of its own new task
alarmalert使用singleInstance。只有一個警報活動在一個時間,它總是自己的任務。它啟動的任何東西(如果有的話)成為它自己的新任務的一部分
這種模式很少被使用。一些真正的用例是一個用於啟動或應用程序的活動,你是100%肯定只有一個活動。總之,我建議你不要使用這種模式,除非它是真的有必要。
launchMode是規定你自己的Activity啟動的行為模式,而Intent.Flag是你期望由你啟動的其他的Activity是什麼樣的行為模式
除了分配啟動模式直接在AndroidManifest.xml,我們也能夠通過所謂的意圖標志更多的行為分配,例如:
Intent intent = new Intent(StandardActivity.this, StandardActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent);
7.1 總結
[1] standard 模式
這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。
[2] singleTop 模式
如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。
[3] singleTask 模式
如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
[4] singleInstance 模式
在一個新棧中創建該Activity的實例,並讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。
最後,資料什麼的都看完了,學習到了很多。最近在寫項目會用到launchMode,將以前模糊不明白的地方,搞懂一些。磨刀不誤砍柴工說的很對,所以先看資料學習,再通過項目練手加深印象。
背景一個典型的ListView,每個Item顯示一個TextView,代表一個Task,需要實現二個編輯方式:一個是用CheckBox來標識任務已經完成,另一個要實現的編
Activities提供了一種方便管理的創建、保存、回復的對話框機制,例如 onCreateDialog(int), onPrepareDialog(int, Dialo
getPixels()void getPixels (int[] pixels, int offset,
本篇文章講的是Android 自定義ViewGroup之實現標簽流式布局-FlowLayout,開發中我們會經常需要實現類似於熱門標簽等自動換行的流式布局的功能,網上也有