當前位置:首頁 » 安卓系統 » android啟動一個activity

android啟動一個activity

發布時間: 2023-02-18 02:53:34

⑴ Android 是怎麼啟動一個Acitivity的

可以把啟動過程分為client端和server端。
一、client端在啟動一個Activity時進行的工作
備註:我個人理解,client端指的是相對後台ActivityManagerService 進程來說的前台用戶可見的進程,如在界面啟動某一個Activity的就是Laucher進程。這里則以從home桌面啟動一個Activity來分析啟動過程:
(1)Launcher 這個進程的主線程,在捕獲onClick點擊事件後,調用 startActivitySafely 方法, startActivitySafely 方法內部調用了
startActivity 方法,然後,startActivity方法進而調用Launcher的父類Activity的 startActivity方法;
(2)Activity.startActivity方法 調用startActivityForResult 方法,傳入該方法 的requestCode 參數為 -1 ,表示 Activity啟動成功後,不需要執行 Lanucher.onActivityResult方法處理返回結果;startActivityForResult方法內部需要調用 Instrumentation 的 execStartActivity方法。Instrumentation 對象是用於監控應用程序和系統(主要是 Activity Manager )的交互過程。
(3)execStartActivity方法會把將要啟動的Activity相關信息傳送到ActivityManagerService 如果 ActivityMonitor 對啟動Activity 進行檢查沒問題,那麼會調用 ActivityManagerNative.getDault 得到ActivityManagerProxy代理對象,然後調用該代理對象的startActivity方法。;
(4)調用ActivityManagerProxy代理對象的startActivity方法實際上是調用 BinderProxy.transact向 Binder驅動發送 START_ACTIVITY_TRANSACTION命令,此時就從Lanucher進程切換到ActivityManagerService進程了。
總結上述四步:源Activity(這里是Launcher)所屬進程通過一系列方法,(無論是通過Launcher來啟動Activity,還是通過Activity內部調用startActivity介面來啟動新的Activit),都通過Binder進程間通信進入到ActivityManagerService進程中,並且調用ActivityManagerService.startActivity介面;

二、Lanucher進程處理Activity的啟動請求,就是Client端的工作,傳遞給 Server端的 ActivityManagerService 後。就是ActivityManagerService 進程的處理過程 了。
處理過程將分為 7個階段
1、第一階段——預啟動檢查
這個階段,主要工作是檢查是否有許可權啟動該Activity,查詢系統中是否存在指定Intent的Activity, 檢查Intent是否正確,檢查當前能否切換Activity,各種檢查通過後創建目標Activity的ActivityRecord, 判斷是否有可復用的Task 或者Activity ,有則關聯ActivityRecord,無則新建Task ,更新 ActivityManagerService中Task的數量,檢查回退棧頂是否有顯示的Activity,有則暫停。
2、第二階段——暫停
這個階段的主要工作就是暫停啟動目標 Activity的源Activity,比如,我是從Actvity A啟動Activity B的,那麼在啟動B之前需要把A暫停,
針對暫停的Activity的後續處理,要麼是執行destroy 操作,要麼是存入等待stop列表;
3、第三階段——創建目標Activity所運行的進程
准備切換動畫,查詢ActivityManagerService 的mProcessNames變數中是否存在指定的進程信息,有則復用,直接啟動Activity,無則通過zygote啟動一個新的進程。進程啟動超時時間一般是10s。
4、第四階段——載入應用程序Activity
進程入口是 ActivityThread 的main方法,main方法里的主要工作是設置臨時進程名,創建 UI主線程ActivityThread ,並調用其attach方法,最後進入主線程的消息循環。接下來的工作是為低內存設備禁用硬體加速,創建應用程序對應的Application, 並初始化,安裝 Content Provider,執行Instrumentation的onCreate方法,執行Application的 onCreate方法。
5、第五階段——顯示Acitivity
在ActivityManagerService 所在進程向應用程序主線程的消息循環發送 LANUCHER_ACTIVITY消息,然後在主線程中回調Activity生命周期的onCreate, onStart,onResume等方法來顯示 Activity,onResume方法執行完畢後,需要先把當前顯示Activity所在的Task加入最近Task列表,然後才返回ActivityManagerService作後續處理。(在onResume方法之前,還可能會先回調onNewIntent 和 onActivityResult方法)

6、第六階段——處理處於空閑狀態的Activitiy
包括移除ActivityStack消息循環中的超時MSG,停止待停止列表總得Activity,銷毀待銷毀的Activity,如果是系統啟動階段,還要發送一個ACTION_BOOT_COMPLETEED廣播,回收待回收應用程序進程等。最重要的一個操作就是停止源Activity 。

備註:此文是讀書所得,主要歸納於老羅的《Android 源代碼情景分析》和楊雲君老師的《Android的設計與實現I》。

⑵ android線程里怎麼啟動一個ACTIVITY-CSDN論壇

  1. CSDN論壇是個討論的地方,下載資源的地方

  2. android子線程不能進行ui操作

  3. android子線程可以通過handler發送消息,然後主線程啟動ACTIVITY

  4. 啟動activity,可以startActivity和startActivityForResult

⑶ 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並且完後需要返回到啟動他的activity來執行的回調函數是

1、首先在打開的xml界面中,定義一個按鈕,如下圖所示。

⑸ Activity啟動流程:Hook實現啟動未注冊Activity

本文介紹在Android中啟動未在AndroidManifest中注冊的Activity的一個解決方案。主要需要掌握以下知識點:

Activity默認都需要在AndroidManifest中注冊,未注冊的應用無法啟動。AMS在啟動應用時,會檢測是否已經注冊。因此,如果想要啟動未注冊的Activity,那麼需要在Activity前,替換啟動應用的Intent為已經注冊過的Activity,因此可以新建一個Activity,用於佔位。在檢測通過後,真正啟動Activity前再替換回需要啟動的未注冊的Activity。

調用startActivity方法後,最後都會在Instrumentation的execStartActivity方法中調用AMS的遠程方法進行處理。Android6.0及以下和Android6.0以上,在execStartActivity中調用AMS的方法有所不同,因此需要做兼容處理。

通過調用ActivityManagerNative.getDefault()來獲取AMS。

通過調用ActivityManager.getService()來獲取AMS。

啟動Activity的消息,會回調到ActivityThread中的mH的dispatchMessage方法,可以通過給mH設置一個callBack,在callBack的handleMessage中,然後替換回真正要啟動的Intent,然後返回false,讓handleMessage再繼續處理。

Android8.0及以下,在ActivityThread的mH中的handleMessage方法中,會處理LAUNCH_ACTIVITY類型的消息,在這里調用了handleLaunchActivity方法來啟動Activity。

和8.0一樣,設置callBack,然後修改Intent。

在ActivityThread的mH中的handleMessage方法中,會處理EXECUTE_TRANSACTION類型的消息,在這里調用了TransactionExecutor.execute方法

execute方法中會調用executeCallbacks

這個方法里會調用ClientTransactionItem的execute方法。ClientTransactionItem是在ActivityStackSupervisor中的realStartActivityLocked中添加的

因此,ClientTransactionItem對應的具體類為LaunchActivityItem,它對應的execute方法

在它的方法里又調用了ClientTransactionHandler的handleLaunchActivity,而ClientTransactionHandler就是在ActivityThread中定義的

ActivityThread繼承了ClientTransactionHandler,那麼它就會實現handleLaunchActivity。最終在這個方法里啟動Activity

到這里,就可以啟用同一應用內未注冊的Activity。

啟動非同一應用內的Activity,相比啟動同一應用內的Activity,需要多幾個步驟。由於不在一個應用內,所以需要把插件的APK先載入進來,然後同樣也需要在AMS檢測前替換Intent為佔位的Intent,在檢測後,啟動Activity前替換回為需要啟動Activity的Intent。另外,由於插件是動態載入進去的,也需要解決資源載入的問題。

載入插件主要是用到類載入器

這個過程和應用內的情況是一樣的,不再贅述

載入資源主要用到AssetManager的addAssetPath方法,通過反射來載入

https://github.com/milovetingting/Samples/tree/master/PluginDemo

⑹ android 怎麼設置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 }

如何設置Activity的啟動模式

  • Activity的四種啟動模式:standard:這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。 singleTop: 如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放...

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啟動時的策略,在AndroidManifest.xml中的標簽的android:launchMode屬性設置;
啟動模式有4種,分別為standard、singleTop、singleTask、singleInstance;
講解啟動模式之前,有必要先了解一下「任務棧」的概念;
一 :
standard 模式:這個就沒有什麼好說的了,Android默認Activity啟動的模式 就是 standard,如果有3個 Activity,Act1,Act2,Act3, 如果從Act1 啟動到Act2 ,在啟動到Act3,那麼Android 的任務棧(task stack)分別為 Act1、Act2、Act3,Act3 在棧頂,如果此時按手機返回鍵,則需要返回3次才能返回到桌面(假設是從桌面啟動的demo),任務棧分銷毀掉 Act3,Act2,最後Act1 。
二 :singleTop模式:
實驗效果:
singleTop模式:該啟動模式和standard模式相差不多,任務棧分配也很相似,如:現有 act1,act 2,在act2 清單文件中配置 android:launchMode="singleTop" ,其他都是默認standard 模式, 若從桌面啟動該實驗demo,從act 1,到act2 ,那麼任務棧則分配為,act1,act2,此時該任務棧和 standard 模式任務棧分配則完全相同,接下來則說明不同的地方,如果在act2 界面中 啟動 到act1, 此時的 任務棧 情況則為 act1,act2,act1,在由act1 啟動到act2,在啟動到act2,進行多次啟動,(在act2界面)任務棧的情況則為,act1,act2,act1,act2,棧頂的act2 則不會重新創建,則會復用act2 該 Activit, 依次類推。
理論知識:
singleTop,如果任務棧的棧頂元素是要被激活的組件,不會創建新的Activity放在任務棧,而是會復用棧頂的Activity。 如果發現棧頂的元素不是要激活的Activity,就會創建新的Activity 放置到任務棧裡面
singleTop模式應用場景 :
App程序中(或瀏覽器中)保存的書簽,假如用戶看到一個界面保存自己喜歡的標簽,假如要保存10個,這個時候用戶在返回鍵的時候,則會返回10次才能返回到App應用中, Android下singleTop 則解決該問題。
三singleTask 模式 :
實驗效果 相差不大,實驗內容就不多說了,自己可以寫個小demo,兩個Activity,每個Activiy 有兩個button,可以相互啟動 打日誌去動手查看,會理解更加深刻,可以參照著 SingleTop模式去實驗,以下只是講解下 和SingleTop的區別:
區別如下:(理論知識)
SingleTask 操作模式,一般和singleTop操作模式類似,如果他發現任務棧裡面已經有了要啟動的這個Activity,他會清空這個Activity所在的任務棧上面的所有Activiy,然後直接復用這個已經存在的Activity 。
應用場景:
如果一個App中,有一個功能需要載入網頁內容 ,打開一個 browserActiviy現在網頁內容,則內存開銷非常大,首先要初始化webkit /c++ 嵌入式瀏覽器內核broweractivity 配置了singleTask,空間換時間,使用該模式可以節省內存開銷。
四 :singleinstance 模式 :
直接理論知識吧」:
singleInstance操作模式會新開啟一個任務棧,跟其他普通Activity不是 同一個任務棧,比較牛,他的模式流程是 首先要新開啟一個新的任務棧把要激活的Activity放置到新的 任務棧里,這個任務棧裡面只有且 只有一個實例,也比較極端吧。說比較極端也跟他的應用場景有關系。
應用場景 :
App各種詞典,向有道詞典,什麼金山詞典,說極端是因為不想被放置到同一個任務棧裡面,它是全局的系統程序應用,達到節省內存的使用目的。

win7 系統 怎麼設置uefi啟動模式

存有ghost版win7系統iso鏡像文件的u啟動uefi u盤啟動盤插在電腦u *** 介面上,然後重啟電腦,在出現開機畫面時用一鍵u盤啟動快捷鍵的方法進入到啟動項選擇窗口,然後將游標移至UEFI:開頭的項(注意:一定要選擇該項),按回車鍵執行等待進入到u啟動win pe系統,u啟動裝機工具會自動開啟,並載入到u啟動uefi u盤啟動盤中准備的win7系統安裝程序,點擊選擇c盤為系統安裝盤,再點擊「確定」按鈕繼續
隨即會彈出一個詢問是否執行該操作的提示窗口,點擊「確定」按鈕執行操作
然後耐心等待win7系統釋放完成並自動重啟電腦即可
電腦重啟後會完成系統後續程序安裝應用,直到進入win7系統桌面即可

android開發 activity啟動模式中singleTop的疑問

樓主的這一段理論似乎有點不太准確 「在D完成操作以後,我啟動了系統內置的瀏覽器E,根據sdk的說法,瀏覽器E被放進了一個新任務。那麼現在有兩個任務」 你憑什麼確定瀏覽器E被放進了一個新的Task呢? 在啟動瀏覽器E的Intent里設置了flag? intentandroid開發 activity啟動模式中singleTop的疑問

android-Android activity 的啟動模式.新人提問,大俠在哪

Activity的四種啟動模式:standard:這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。
singleTop: 如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。
singleTask:如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
singleInstance:在一個新棧中創建該Activity的實例,並讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。
位置在 AndroidManifest.xml 文件中 Activity 元素的 android:launchMode 屬性。
不知道你要問什麼,為你解答

activity的啟動模式有哪些

Activity的四種啟動模式:standard:這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。
singleTop: 如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。
singleTask:如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
singleInstance:在一個新棧中創建該Activity的實例,並讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。
位置在 AndroidManifest.xml 文件中 Activity 元素的 android:launchMode 屬性。

⑺ Android中的Activity詳解--啟動模式與任務棧

目錄

activity的簡單介紹就不寫了,作為最常用的四大組件之一,肯定都很熟悉其基本用法了。

首先,是都很熟悉的一張圖,即官方介紹的Activity生命周期圖.

情景:打開某個應用的的FirstActivity調用方法如下:
由於之前已經很熟悉了,這里就簡單貼一些圖。

按下返回鍵:

重新打開並按下home鍵:

再重新打開:

在其中打開一個DialogActivity(SecondActivity)

按下返回:

修改SecondAcitvity為普通Activity,依舊是上述操作:

這里強調一下 onSaveInstanceState(Bundle outState) 方法的調用時機:
當Activity有可能被系統殺掉時調用,注意,一定是被系統殺掉,自己調用finish是不行的。
測試如下:FirstActivity啟動SecondActivity:

一個App會包含很多個Activity,多個Activity之間通過intent進行跳轉,那麼原始的Activity就是使用棧這個數據結構來保存的。
Task
A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened.
即若干個Activity的集合的棧表示一個Task。
當App啟動時如果不存在當前App的任務棧就會自動創建一個,默認情況下一個App中的所有Activity都是放在一個Task中的,但是如果指定了特殊的啟動模式,那麼就會出現同一個App的Activity出現在不同的任務棧中的情況,即會有任務棧中包含來自於不同App的Activity。

標准模式,在不指定啟動模式的情況下都是以此種方式啟動的。每次啟動都會創建一個新的Activity實例,覆蓋在原有的Activity上,原有的Activity入棧。
測試如下:在FirstActivity中啟動FirstActivity:

當只有一個FirstActivity時堆棧情況:

此種模式下,Activity在啟動時會進行判斷,如果當前的App的棧頂的Activity即正在活動的Activity就是將要啟動的Activity,那麼就不會創建新的實例,直接使用棧頂的實例。
測試,設置FirstActivity為此啟動模式,多次點擊FirstActivity中的啟動FirstActivity的按鈕查看堆棧情況:
(其實點擊按鈕沒有啟動新Activity的動畫就可以看出並沒有啟動新Activity)

大意就是:
對於使用singleTop啟動或Intent.FLAG_ACTIVITY_SINGLE_TOP啟動的Activity,當該Activity被重復啟動(注意一定是re-launched,第一次啟動時不會調用)時就會調用此方法。
且調用此方法之前會先暫停Activity也就是先調用onPause方法。
而且,即使是在新的調用產生後此方法被調用,但是通過getIntent方法獲取到的依舊是以前的Intent,可以通過setIntent方法設置新的Intent。
方法參數就是新傳遞的Intent.

1.如果是同一個App中啟動某個設置了此模式的Activity的話,如果棧中已經存在該Activity的實例,那麼就會將該Activity上面的Activity清空,並將此實例放在棧頂。
測試:SecondActivity啟動模式設為singleTask,啟動三個Activity:

這個模式就很好記,以此模式啟動的Activity會存放在一個單獨的任務棧中,且只會有一個實例。
測試:SecondActivity啟動模式設為singleInstance

結果:

顯然,啟動了兩次ThirdActivity任務棧中就有兩個實例,而SecondActivity在另外一個任務棧中,且只有一個。

在使用Intent啟動一個Activity時可以設置啟動該Activity的啟動模式:
這個屬性有很多,大致列出幾個:

每個啟動的Activity都在一個新的任務棧中

singleTop

singleTask

用此種方式啟動的Activity,在它啟動了其他Activity後,會自動finish.

官方文檔介紹如下:

這樣看來的話,通俗易懂的講,就是給每一個任務棧起個名,給每個Activity也起個名,在Activity以singleTask模式啟動時,就檢查有沒有跟此Activity的名相同的任務棧,有的話就將其加入其中。沒有的話就按照這個Activity的名創建一個任務棧。
測試:在App1中設置SecondActivity的taskAffinity為「gsq.test」,App2中的ActivityX的taskAffinity也設為「gsq.test」

任務棧信息如下:

結果很顯然了。
測試:在上述基礎上,在ActivityX中進行跳轉到ActivityY,ActivityY不指定啟動模式和taskAffinity。結果如下:

這樣就沒問題了,ActivityY在一個新的任務棧中,名稱為包名。
這時從ActivityY跳轉到SecondActivity,那應該是gsq.test任務棧只有SecondActivity,ActivityX已經沒有了。因為其啟動模式是singleTask,在啟動它時發現已經有一個實例存在,就把它所在的任務棧上面的Activity都清空了並將其置於棧頂。

還有一點需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由於SecondActivity並沒有指定MAIN和LAUNCHER過濾器,故在FirstActivity跳轉到SecondActivity時,按下home鍵,再點開App1,回到的是FirstActivity。

大致就先寫這么多吧,好像有點長,廢話有點多,估計也有錯別字,不要太在意~~~

⑻ android 啟動 activity 是什麼意思

當應用運行起來後就會開啟一條線程,線程中會運行一個任務棧,當Activity實例創建後就會放入任務棧中。Activity啟動模式的設置在AndroidManifest.xml文件中,通過配置Activity的屬性android:launchMode=""設置。

1. Standard模式(默認)

我們平時直接創建的Activity都是這種模式的Activity,這種模式的Activity的特點是:只要你創建了Activity實例,一旦激活該Activity,則會向任務棧中加入新創建的實例,退出Activity則會在任務棧中銷毀該實例。

2. SingleTop模式

這種模式會考慮當前要激活的Activity實例在任務棧中是否正處於棧頂,如果處於棧頂則無需重新創建新的實例,會重用已存在的實例,否則會在任務棧中創建新的實例。

3. SingleTask模式

如果任務棧中存在該模式的Activity實例,則把棧中該實例以上的Activity實例全部移除,調用該實例的newInstance()方法重用該Activity,使該實例處於棧頂位置,否則就重新創建一個新的Activity實例。

4. SingleInstance模式

當該模式Activity實例在任務棧中創建後,只要該實例還在任務棧中,即只要激活的是該類型的Activity,都會通過調用實例的newInstance()方法重用該Activity,此時使用的都是同一個Activity實例,它都會處於任務棧的棧頂。此模式一般用於載入較慢的,比較耗性能且不需要每次都重新創建的Activity。

⑼ android 如何打開一個新的activity

1、設置Intent

java">Intentintent=newIntent(當前Activity.this,要打開的Activity.class);

2、通過startActivity打開activity

startActivity(intent);//打開新的activity

⑽ Android Service啟動Activity

Android Service 基礎知識點

我們都知道Activity中啟動Activity,只需要startActivity,如果在Service中啟動Activity呢?

在Service中啟動Activity,很多人說在非Activity中啟動Activity需要加FLAG_ACTIVITY_NEW_TASK flag,如果我不加會怎麼樣呢?

並沒有出現異常和崩潰,跳轉也是正常的,但是與之前所說的會崩潰報出異常不符合啊?!難道是與版本有關嗎?於是我使用了Android 23去測試果然拋出了異常

ContextImpl在Android studio中屬於隱藏源碼,在IDE中可能看不到,那就需要在SDK中去找 我的是:D:\AndroidSdk\sources\android-23\android\app\ContextImpl.java

可以看到只是判斷條件不同而已,android-23中發現沒有Intent.FLAG_ACTIVITY_NEW_TASK會直接拋出異常,而android-26中我們在非 Activity 調用 startActivity() 的時候,我們這個 options 通常是 null 的,所以在 26 之間的時候,誤把判斷條件 options == null 寫成了 options != null 導致進不去 if,從而不會拋出異常

附加:在android 24-android 27(即android N-android O)之間出現了bug,也就是說即使沒有加Intent.FLAG_ACTIVITY_NEW_TASK也會正常跳轉

可以很明顯看到判斷條件targetSdkVersion < Build.VERSION_CODES.N || targetSdkVersion >= Build.VERSION_CODES.P 即在24-27

看Activity中啟動Activity的源碼

Activity.startActivity() ->startActivityForResult()->mInstrumentation.execStartActivity() ...最終還是Ams去啟動Activity 也就是Activity中重寫了startActivity()方法所以不會出現這個異常

其實直觀很好理解,如果不是在Activity中啟動的,那就可以看做不是用戶主動的行為,也就說這個界面可能出現在任何APP之上,如果不用Intent.FLAG_ACTIVITY_NEW_TASK將其限制在自己的Task中,那用戶可能會認為該Activity是當前可見APP的頁面,這是不合理的。舉個例子:我們在聽音樂,這個時候如果郵件Service突然要打開一個Activity,如果不用Intent.FLAG_ACTIVITY_NEW_TASK做限制,那用戶可能認為這個Activity是屬於音樂APP的,因為用戶點擊返回的時候,可能會回到音樂,而不是郵件(如果郵件之前就有界面)

對比源碼發現,在我們非 Activity 調用 startActivity() 的時候,我們這個 options 通常是 null 的,所以在 24~27 之間的時候,誤把判斷條件 options == null 寫成了 options != null 導致進不去 if,從而不會拋出異常,如此我們使用 Context.startActivity() 的時候是一定要加上 FLAG_ACTIVITY_NEW_TASK 的,但是在 Android N 到 O-MR1,即 24~27 之間卻出現了 bug,即使沒有加也會正確跳轉

結語:感謝各位大佬的分享,對此有疑問的可以去運行跑一下,看一下相關的源碼,如有錯誤的需要改進的地方,請留言評論指出,謝謝!

參考文章:

熱點內容
吃雞低配置手機如何開極致畫質 發布:2025-05-16 18:15:20 瀏覽:191
空密碼訪問 發布:2025-05-16 18:08:51 瀏覽:892
騰訊雲伺服器安全規則設置 發布:2025-05-16 17:51:33 瀏覽:650
k3伺服器不可用怎麼辦 發布:2025-05-16 17:51:30 瀏覽:537
編輯html源碼 發布:2025-05-16 17:45:45 瀏覽:65
邊的存儲方法 發布:2025-05-16 17:33:16 瀏覽:927
海量伺服器怎麼拆 發布:2025-05-16 17:31:07 瀏覽:211
運行與編譯的區別 發布:2025-05-16 17:25:02 瀏覽:824
c語言for中continue 發布:2025-05-16 17:20:14 瀏覽:648
ftp儲存 發布:2025-05-16 17:04:08 瀏覽:506