當前位置:首頁 » 安卓系統 » androidactivity啟動

androidactivity啟動

發布時間: 2024-10-16 04:40:25

Ⅰ Android Activity啟動模式與狀態保存及恢復詳解

       Activity是 Android組件 中最基本也是最為常見用的四大組件(Activity,Service服務,Content Provider內容提供者,BroadcastReceiver廣播接收器)之一 。
       Activity是一個應用程序 組件 ,提供一個 屏幕 ,用戶可以用來交互為了完成某項任務。
       Activity中所有操作都與用戶密切相關,是一個負責與 用戶交互 的組件,可以通過setContentView(View)來 顯示指定控制項
       在一個android應用中,一個Activity通常就是一個單獨的屏幕,它上面可以顯示一些控制項也可以監聽並處理用戶的事件做出響應。Activity之間通過Intent進行通信。
       關於Activity啟動流程請參考之前的文章 Android activity啟動流程分析

       activity有四種啟動模式,分別為standard,singleTop,singleTask,singleInstance。如果要使用這四種啟動模式,必須在manifest文件中<activity>標簽中的launchMode屬性中配置。

       標準的默認啟動模式,這種模式下activity可以被多次實例化,即在一個task中可以存在多個activity,每一個activity會處理一個intent對象,(在A中再次啟動A,會存在後面的A在前面的A上面,當前task會存在兩個activity的實例對象)

       如果一個singleTop模式啟動的activity實例已經存在於棧頂,那麼再次啟動這個activity的時候,不會重新創建實例,而是重用位於棧頂的那個實例,並且會調用實例的onNewIntent()方法將Intent對象傳遞到這個實例中,如果實例不位於棧頂,會創建新的實例。

       啟動模式設置為singleTask,framework在啟動該activity時只會把它標示為可在一個新任務中啟動,至於是否在一個新任務中啟動,還要受其他條件的限制,即taskAffinity屬性。
        taskAffinity :默認情況下,一個應用中的所有activity具有相同的taskAffinity,即應用程序的包名。我們可以通過設置不同的taskAffinity屬性給應用中的activity分組,也可以把不同的應用中的activity的taskAffinity設置成相同的值,當兩個不同應用中的activity設置成相同的taskAffinity時,則兩個activity會屬於同一個TaskRecord。
       在啟動一個singleTask的Activity實例時,如果系統中已經存在這樣一個實例,就會將這個實例調度到任務棧的棧頂,並清除它當前所在任務中位於它上面的所有的activity;如果這個已存在的任務中不存在一個要啟動的Activity的實例,則在這個任務的頂端啟動一個實例;若這個任務不存在,則會啟動一個新的任務,在這個新的任務中啟動這個singleTask模式的Activity的一個實例。

       以singleInstance模式啟動的Activity具有全局唯一性,即整個系統中只會存在一個這樣的實例,如果在啟動這樣的Activiyt時,已經存在了一個實例,那麼會把它所在的任務調度到前台,重用這個實例。
       以singleInstance模式啟動的Activity具有獨占性,即它會獨自佔用一個任務,被他開啟的任何activity都會運行在其他任務中(官方文檔上的描述為,singleInstance模式的Activity不允許其他Activity和它共存在一個任務中)。
       被singleInstance模式的Activity開啟的其他activity,能夠開啟一個新任務,但不一定開啟新的任務,也可能在已有的一個任務中開啟,受條件的限制,這個條件是:當前系統中是不是已經有了一個activity B的taskAffinity屬性指定的任務。

       涉及到Activity啟動,就不得不說一下Activity的管理,Activity是以什麼方式及被什麼類來進行管理的,涉及的類主要如下:

       歷史棧中的一個條目,代表一個activity。ActivityRecord中的成員變數task表示其所在的TaskRecord,ActivityRecord與TaskRecord建立了聯系。

       內部維護一個 ArrayList<ActivityRecord> 用來保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord與ActivityStack建立了聯系。

       內部維護了一個 ArrayList<TaskRecord> ,用來管理TaskRecord,ActivityStack中持有ActivityStackSupervisor對象,由ActivityStackSupervisor創建。

       負責所有ActivityStack的管理。內部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是當前顯示在前台Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前台Activity的Activity棧。

       ActivityThread 運行在UI線程(主線程),App的真正入口。

       用來實現AMS和ActivityThread之間的交互。

       負責調用Activity和Application生命周期。

       當一個Activity未被主動關閉,即「被動關閉」時,可能需要系統給用戶提供保持一些狀態的入口。

       前面說的入口就是:Activity提供了onSaveInstanceState()方法,該方法是Activity在關閉前保存狀態的核心方法。

       前面提到「被動關閉」,如果是主動關閉那麼就不會調用,比如:按back鍵、調用finish()等,那麼"被動關閉"的場景有哪些呢?下面給列舉一下:

       肯定在調用onStop()前被調用,但不保證在onPause()前 / 後,一般是在onPause()後調用。

       當需要保持狀態時,在onSaveInstanceState()內執行以下邏輯:

       當需要恢復時,在onCreate()內部執行以下邏輯:

       布局每個View默認實現:onSaveInstanceState(),即UI的任何改變都會自動的存儲和在activity重新創建的時候自動的恢復(只有在為該UI提供了唯一ID後才起作用);
       若需復寫該方法從而存儲額外的狀態信息時,應先調用父類的onSaveInstanceState()(因為默認的onSaveInstanceState()幫助UI存儲它的狀態);
       只使用該方法記錄Activity的瞬間狀態(UI的狀態),而不是去存儲持久化數據,因為onSaveInstanceState()調用時機不確定性;可使用 onPause()[一定會執行]存儲持久化數據;

       Activity提供了onRestoreInstanceState()方法,該方法是Activity在重新創建後恢復之前保存狀態的核心方法。

       若被動關閉了Activity,即調用了onSaveInstanceState(),那麼下次啟動時會調用onRestoreInstanceState()。

       onCreate()--->onStart()--->onRestoreInstanceState()--->onResume()

        注意: onSaveInstanceState()、onRestoreInstanceState()不一定 成對被調用
       如:當正在顯示Activity A時,用戶按下HOME鍵回到主界面,然後用戶緊接著又返回到Activity A,此時Activity A一般不會因為內存的原因被系統銷毀,故Activity A的onRestoreInstanceState()不會被執行;
       針對以上情況,onSaveInstanceState保持的參數可以選擇在onCreate()內部進行解析使用,因為onSaveInstanceState的bundle參數會傳遞到onCreate方法中,可選擇在onCreate()中做數據還原。
        至此:Activity的啟動模式及Activity的狀態保持及恢復介紹完畢。

Ⅱ android 怎麼設置activity的啟動模式

在Android中每個界面都是一個Activity,切換界面操作其實是多個不同Activity之間的實例化操作。在Android中Activity的啟動模式決定了Activity的啟動運行方式。
Android總Activity的啟動模式分為四種:

Activity啟動模式設置:

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

Activity的四種啟動模式:

1. standard

模式啟動模式,每次激活Activity時都會創建Activity,並放入任務棧中。

2. singleTop

如果在任務的棧頂正好存在該Activity的實例, 就重用該實例,否者就會創建新的實例並放入棧頂(即使棧中已經存在該Activity實例,只要不在棧頂,都會創建實例)。

3. singleTask

如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的onNewIntent())。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧。如果棧中不存在該實例,將會創建新的實例放入棧中。

4. singleInstance

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

其中standard是系統默認的啟動模式。

下面通過實例來演示standard的運行機制:

1 private TextView text_show;
2 private Button btn_mode;
3
4 @Override
5 public void onCreate(Bundle savedInstanceState) {
6 super.onCreate(savedInstanceState);
7 setContentView(R.layout.activity_main);
8
9 text_show = (TextView) this.findViewById(R.id.text_show);
10
11 text_show.setText(this.toString());
12
13 btn_mode = (Button) this.findViewById(R.id.btn_mode);
14
15 }
16
//按鈕單擊事件
17 public void LaunchStandard(View v){
18 startActivity(new Intent(this,MainActivity.class));
19
20 text_show.setText(this.toString());
21 }

Ⅲ android 主activity用什麼啟動模式

在android里,有4種activity的啟動模式,分別為:
「standard」 (默認)
「singleTop」
「singleTask」
「singleInstance」

1. 如何決定所屬task
「standard」和」singleTop」的activity的目標task,和收到的Intent的發送者在同一個task內,除非intent包括參數FLAG_ACTIVITY_NEW_TASK。
如果提供了FLAG_ACTIVITY_NEW_TASK參數,會啟動到別的task里。
2. 是否允許多個實例
「standard」和」singleTop」可以被實例化多次,並且存在於不同的task中,且一個task可以包括一個activity的多個實例;
「singleTask」和」singleInstance」則限制只生成一個實例,並且是task的根元素。
singleTop要求如果創建intent的時候棧頂已經有要創建 的Activity的實例,則將intent發送給該實例,而不發送給新的實例。

3. 是否允許其它activity存在於本task內
「singleInstance」獨佔一個task,其它activity不能存在那個task里;如果它啟動了一個新的activity,不管新的activity的launch mode 如何,新的activity都將會到別的task里運行(如同加了FLAG_ACTIVITY_NEW_TASK參數)。
而另外三種模式,則可以和其它activity共存。

4. 是否每次都生成新實例
「standard」對於沒一個啟動Intent都會生成一個activity的新實例;
「singleTop」的activity如果在task的棧頂的話,則不生成新的該activity的實例,直接使用棧頂的實例,否則,生成該activity的實例。
比如現在task棧元素為A-B-C-D(D在棧頂),這時候給D發一個啟動intent,如果D是 「standard」的,則生成D的一個新實例,棧變為A-B-C-D-D。
如果D是singleTop的話,則不會生產D的新實例,棧狀態仍為A-B-C-D
如果這時候給B發Intent的話,不管B的launchmode是」standard」 還是 「singleTop」 ,都會生成B的新實例,棧狀態變為A-B-C-D-B。

「singleInstance」是其所在棧的唯一activity,它會每次都被重用。

「singleTask」如果在棧頂,則接受intent,否則,該intent會被丟棄,但是該task仍會回到前台。

當已經存在的activity實例處理新的intent時候,會調用onNewIntent()方法
如果收到intent生成一個activity實例,那麼用戶可以通過back鍵回到上一個狀態;如果是已經存在的一個activity來處理這個intent的話,用戶不能通過按back鍵返回到這之前的狀態。

總結如下:
standard 每次都會新建,每個Task都可以有,且每個Task都可以有多個實例(每個Task都可以有,且可以有多個)
singleTop 當前實例如果在棧頂,就不新建實例,調用其OnNewIntent。 如不在棧頂,則新建實例 (每個Task都可以有,且可以有多個,在棧頂時可復用)
singleTask 新建一個Task,如果已經有其他的Task並且包含該實例,那就直接調用那個Task的實例。(只有一個Task中會有)
singleInstance 新建一個Task,且在該Task中只有它的唯一一個實例。 (只有一個Task會有,且該Task中只有它)

FLAG_ACTIVITY_NEW_TASK 類似singleTask
FLAG_ACTIVITY_SINGLE_TOP 類似singleTop
FLAG_ACTIVITY_CLEAR_TOP 無對應

Ⅳ Android —— Activity的四種啟動模式

除了Activity的生命周期外,Activity的啟動模式也是一個難點,有時候為了滿足項目的特殊需求,就必須使用Activity的啟動模式。

在默認情況下,當我們多次啟動同一個Activity的時候,系統會創建多個實例並把它們放入任務棧中,但是有些場景重復創建多個實例,是沒有必要且浪費資源的,這就需要啟動模式來修改系統的默認行為。

下面,我將以理論+實踐的形式為大家介紹Activity的啟動模式。

這是系統的默認啟動模式,採用這種模式的Activity無論是否已經存在實例,都會重新創建一個實例,在這種模式下誰啟動了這個Activity,那麼這個Activity就運行在啟動它的那個Activity所在的棧中。

實踐:MainActivity 採用 standard 模式

在這種模式下,如果新的Activity已經位於任務棧的棧頂,那麼此Activity不會被重新創建,同時它的 NewIntent 方法將會被回調。如果新Activity的實例已存在但不是位於棧頂,那麼新Activity依然會被創建。

實踐:MainActivity 採用 singleTop 模式

MainActivity 採用 singleTop 模式,SecondActivity採用 standard 模式

這是一種單實例模式,在這種模式下,只要Activity在一個棧中存在,那麼多次啟動此Activity都不會重新創建實例,而是回調 onNewIntent() 。

實踐:MainActivity 採用 singleTask 模式

MainActivity 採用 singleTask 模式,SecondActivity採用 standard 模式

這是一種加強的 singleTask 模式,它除了具有 singleTask 模式的所有特性外,還加強了一點,那就是具有此模式的Activity只能單獨的位於一個任務棧中。

實踐:MainActivity 採用 singleInstance 模式

MainActivity 採用 singleInstance 模式,SecondActivity採用 standard 模式

以上就是Activity啟動模式的介紹。

歡迎留言指出錯誤。

熱點內容
ftp匿名登錄名為 發布:2024-10-16 08:08:07 瀏覽:278
安卓手機為什麼關不了屏幕 發布:2024-10-16 08:06:24 瀏覽:650
法師需要什麼配置 發布:2024-10-16 07:57:34 瀏覽:546
查詢資料庫用戶的許可權 發布:2024-10-16 07:51:18 瀏覽:438
安卓flv播放器哪個好 發布:2024-10-16 07:45:46 瀏覽:595
預演算法的類型 發布:2024-10-16 07:42:04 瀏覽:315
王者榮耀安卓哪個平台好 發布:2024-10-16 07:20:34 瀏覽:105
android獲取屏幕解析度 發布:2024-10-16 07:20:32 瀏覽:589
cf手游腳本文件 發布:2024-10-16 07:11:37 瀏覽:662
python35pygame 發布:2024-10-16 07:05:35 瀏覽:923