當前位置:首頁 » 安卓系統 » android單activity

android單activity

發布時間: 2023-03-17 11:31:45

Ⅰ 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是 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 運行模式與回退棧

LaunchMode 定義的是activity實例與task之間的關系,可以通過下面的兩種方式來定義:

在Activity A中啟動B,可以利用Activity B在清單中的launchmode定義,也可以在A中調用startActivity()的時候通過intent的flag傳入,當兩種方式都有定義,intent的flag參數會覆蓋掉B原有的定義。

利用Activity 元素的launchMode屬性
launchMode屬性指定Activity如何被運行到一個task中。launchMode的值有四種:

默認, 每次啟動Activity系統都會產生一個新的實例,並且把intent發送給新產生的實例,這個Activity可以被實例化多次,每個實例可以屬於不同的task,每個task也可以保有多個此Activity的實例。

如果當前task 的回退棧棧頂已經存在一個此Activity的實例,系統通過調用這個實例的onNewIntent()方法把intent發送給這個Activity實例,而不是創建一個新的此Activity的實例。這個Activity也可以被實例化多次,每個實例可以屬於不同的task,每個task可一個保有多個實例(僅限於此Activity已存在的實例不在棧頂)
注意:
應用場合如下:不想出現2個同樣的activity在頂部。比如用戶正在一個activity閱讀信息,這時來了notification,用戶點擊後應該更新這些信息,而不是新建一個activity,這樣在點擊back時,就不會出現回到舊信息activity的情況了。這種情況正是下面這段英語提到的。
Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent()
.
例如,當前回退棧中有A,B,C,D四個Activity,全部是Standard,在D中調用startActivity()去啟動B,intent的flag設置成FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK,系統發現棧中有B,會先銷毀這個B,再原位置重建B,清空CD,而不是把這個新建的B的實例壓入棧頂,這里之所以會銷毀B再新建B,因為B的launchmode是Standard,無論什麼情況下啟動,都需要new一個B的實例,但如果此時B是SingleTop的,系統會把這個intent通過onNewIntent傳給已經在棧中的B的實例,不需要銷毀再創建,仍需要清空CD。

系統會創建一個新的task並且把這個實例放在棧底( 此處有疑問,測試發現並不一定是棧底 ),但是,如果在一個單獨的task中已經存在一個此Activity的實例,系統會把intent通過onNewIntent()發送給這個實例( 測試發現如果在回退棧中,該Activity的上面還有其他Activity,啟動此Activity會清空棧中此Activity上面的其他Activity ),而不是創建一個新的實例。同一時間在只有一個此Activity的實例存在於系統中。

與SingleTask一樣,不同的是SingleTask的Activity所在的task中可以有其他的Activity,而SingleInstance的Activity獨佔一個task,並且在整個系統中只有唯一的一個實例。由這個Activity啟動的其他Activity都會在新的task中打開。

另一個例子,系統自帶瀏覽器APP把瀏覽器Activity聲明為SingleTask,通過在Activity標簽里的launchMode進行指定,這意味著如果你發送一個intent啟動瀏覽器,不管是為瀏覽器新開啟一個task還是從瀏覽器已經在後台保有的task中啟動瀏覽器,瀏覽器Activity與你的APP不在同一個task。

不管一個Activity是不是在一個新的task中啟動,點擊返回都會返回前一個Activity。不過,如果啟動一個LaunchMode為singleTask的Activity,如果該Activity此時在一個處於後台的task中,整個task會變成前台task,此時,回退棧會包含由這個後台task攜帶過來所有Activity,放在回退棧的棧頂,下圖說明這種情況。

在一個新的task里啟動Activity. 如果已經有Activity實例運行在某一task中,啟動這個Activity會把該實例所在的task帶到前台,由該實例的onNewIntent()來接收新的intent。

如果被啟動的Activity就是當前的Activity,這個已經存在的實例通過onNewIntent()接收intent,不會產生新的實例。

被啟動的Activity如果已經存運行於當前task,回退棧中所有在此Activity上面的Activity都將被銷毀,此Activity通過onNewIntent()接收新的intent。
例如,一個task中有A,B,C,D,四個Activity,如果D 調用startActivtiy()啟動Activity B,C和D會被銷毀,B接收這個intent,回退棧中有A,B。
上例中的Activity B的實例,或者通過onNewIntent()接收新的intent,或者銷毀新建來處理新的intent。如果B的launchmode是standard,並且沒有設置FLAG_ACTIVITY_SINGLE_TOP,那麼B會被銷毀重啟,如果是其他launchmode或者設置了FLAG_ACTIVITY_SINGLE_TOP,則會通過onNewIntent()接收。
FLAG_ACTIVITY_CLEAR_TOP 和FLAG_ACTIVITY_NEW_TASK結合使用會有個不錯的效果。
如果啟動的Activity位於task的底部,它會把所在task帶到前台,並且清理狀態至root狀態,當從通知欄里打開一個Activity的會非常有用。

Affinity指的是一個Activity偏向於從屬於哪個task,默認情況下,一個APP內的所有Activity互相之間共享一個affinity的值,所以,所有同一APP下的所有Activity都偏向於從屬於同一個task。但是,這個值是可以更改的,不同APP內的Activity可以共享一個affinity,同一個APP內的Activity也可以被分配不同的affinity的值。
affinity的值可以通過修改Activity標簽的taskAffinity屬性來修改。
這個屬性接收一個String的值,必須在manifest標簽范圍內是唯一的值,因為系統是通過名稱來標識APP的affinity的值的。
Affinity作用於以下兩種情況:

通過startActivity()啟動一個新的Activity時,默認情況下,新的Activity會被壓入與啟動者相同的回退棧中。但是,如果在啟動Activity的時候,使用了FLAG_ACTIVITY_NEW_TASK 這個標志,系統會為新的Activity尋找一個新的task。通常情況下,是一個新的task。但是也並不是必須的。如果系統中有一個task的affinity值與新的Activity的值相同,新的Activity會被分配到這個task中。如果沒有這樣的task,就啟動一個新的task。如果這個標志產生了一個新的task,當用戶點擊home鍵離開的時候,必須要有某種方式能夠使用戶返回到這個task來。有些實體(例如通知管理器)總是從一個外部task中啟動Activity,所以在通過startActivity()啟動新的Activity時總是需要傳遞FLAG_ACTIVITY_NEW_TASK 這個標志。如果你有一個Activity可以被外部實體可能這個標志啟動,注意用戶可以有一種獨立的方式回到啟動它的task,例如點擊啟動圖標。

這種情況下,一個Activity可以動啟動它的那個task移動到它的affinity值對應的task中,當那個task回到前台。例如,假設,一個報告指定城市天氣情況的Activity作為一個旅行APP的一部分,它跟其他處在同一APP的Activity一樣有一個相同的affinity值,並且允許通過這個屬性來調整目標task。當你的一個Activity啟動了這個天氣預報Activity,它默認跟你的Activity在一個task里,但是,當旅行APP進入到前台,這個天氣預報Activity又會被重新分配給旅行APP並且在旅行APP內展示。
提示:
如果一個APK文件從用戶的角度看是多款APP,可能需要這個屬性來設置不同的affinity來關聯不同的APP。

如果用戶離開一個task太長時間,系統會清除task中的所有Activity僅僅保留這下根Activity。當用戶返回到這個task的時候,只有這個根Activity會被恢復。系統通過這種方式來處理,是因為經過相當長的一段時間之後,用戶已經拋棄他們曾經正在做的事情,計劃再回來的時候做點新的事情。

你可以通過如下屬性來更改這種行為:

參考文獻:
Tasks and Back Stack
<activity>
Android 閱讀Tasks and Back Stack文章後的重點摘抄

Ⅳ Android之Activity全面解析,有些知識點容易忘記

Activity作為安卓四大組件之一,是最重要也是用得最多的組件,涉及的知識點非常多,有些知識點平時開發很少用到,但在某些場景下需要特別注意,本文詳細整理了Activity涉及的知識點,供開發參考。

針對Activity可以提出很多問題,如:
Activity 的生命周期?
Activity 之間的通信方式?
Activity 各種情況下的生命周期?
橫豎屏切換時 Activity 的生命周期?
前台切換到後台,然後再回到前台時 Activity 的生命周期?
彈出 Dialog 的時候按 Home 鍵時 Activity 的生命周期?
兩個Activity之間跳轉時的生命周期?
下拉狀態欄時 Activity 的生命周期?
Activity 與 Fragment 之間生命周期比較?
Activity 的四種 LaunchMode(啟動模式)的區別?
Activity 狀態保存與恢復?
Activity的轉場動畫有哪些實現方式?
Activity的生命周期中怎麼獲取控制項寬高?
onNewIntent的執行時機?
如何連續退出多個Activity?

如何把Acitivty設置成Dialog樣式 ,android:theme="@android:style/Theme.Dialog"

關於橫豎屏切換的生命周期,對應不同的手機,由於廠商定製的原因,會有不同的效果,如設置了configChanges="orientation」在有些手機會執行各個生命周期,但有些手機卻不會執行。
網上常見的結論如下:

但實際的測試如下:

可以看出,不同廠商的手機切屏生命周期會有差異。
從API 13以上,當設備在橫豎切屏時,「屏幕尺寸」也會發生變化,因此為了杜絕切屏導致頁面銷毀重建,需要加上screenSize,使用設置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .

Activity的四種狀態如下:

在activity處於paused或者stoped狀態下,如果系統內存緊張,可能會被銷毀,當重回該activity時會重建,正常返回和被回收後返回的生命周期如下:

如果是回收後返回,onCreate的參數savedInstanceState不為空。

有哪些場景會觸發onNewIntent回調呢?跟啟動模式有關,首先該Activity實例已經存在,再次啟動才可能觸發。一種情況是啟動模式是singleTask或者singleInstance,無論該activity在棧中哪個位置,都會觸發onNewIntent回調,並且把上面其他acitivity移除,另一種情況是啟動模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP啟動,並且該activity實例在棧頂,會觸發onNewIntent,如果不在棧頂是重新創建的,不會觸發。

在實際業務開發中,往往碰到需要連續退出多個activity實例,下面整理了幾種常見方法:

● 發送特定廣播
1、在需要處理連續退出的activity注冊該特定廣播;
2、發起退出的activity發送該特定廣播;
3、接收到該廣播的activity 調用finish結束頁面。
● 遞歸退出
1、用startActivityForResult啟動新的activity;
2、前一個頁面finish時,觸發onActvityResult回調,再根據requestCode和resultCode處理是否finish,達到遞歸退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通過intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)啟動新activity,如果棧中已經有該實例,則會把該activity之上的所有activity關閉,達到singleTop啟動模式的效果。
● 自定義activity棧
1、自定義activity列表,新打開activity則加入棧中,關閉則移除棧;
2、需要退出多個activity時,則循環從棧中移除activity實例,並調用finish。

在討論Activity啟動模式經常提到任務棧,那到底什麼是任務棧?
任務是一個Activity的集合,它使用棧的方式來管理其中的Activity,這個棧又被稱為返回棧(back stack),棧中Activity的順序就是按照它們被打開的順序依次存放的。返回棧是一個典型的後進先出(last in, first out)的數據結構。下圖通過時間線的方式非常清晰地向我們展示了多個Activity在返回棧當中的狀態變化:

taskAffinity 任務相關性,可以用於指定一個Activity更加願意依附於哪一個任務,在默認情況下,同一個應用程序中的所有Activity都具有相同的affinity, 名字為應用的包名。當然了,我們可以為每個 Activity 都單獨指定 taskAffinity 屬性(不與包名相同)。taskAffinity 屬性主要和 singleTask 啟動模式和 allowTaskReparenting 屬性配對使用,在其他情況下沒有意義。
taskAffinity 有下面兩種應用場景:

分為顯示啟動和隱式啟動。
(1)顯示啟動
直接指定待調整的Activity類名。

(2)隱式啟動
Intent 能夠匹配目標組件的 IntentFilter 中所設置的過濾信息,如果不匹配將無法啟動目標 Activity。IntentFilter 的過濾信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一個 Activity 中可以有多個 intent-filter
● 一個 intent-filter 同時可以有多個 action、category、data
● 一個 Intent 只要能匹配任何一組 intent-filter 即可啟動對應 Activity
● 新建的 Activity 必須加上以下這句,代表能夠接收隱式調用
<category android:name="android.intent.category.DEFAULT" />

只要匹配一個action即可跳轉,注意的是action要區分大小寫。

規則:如果intent中有category,則所有的都能匹配到intent-filter中的category,intent中的category數量可用少於intent-filter中的。另外,單獨設置category是無法匹配activity的,因為category屬性是一個執行Action的附加信息。

intent不添加category會匹配默認的,即 「android:intent.category.DEFAULT」
如果上面例子,如果去掉intent.setAction("action_name"),則會拋出異常:

規則:類似action,但data有復雜的結構,只要匹配一個data並且與data中所有屬性都一致就能匹配到Activity,只要有1個屬性不匹配,都無法找到activity。
data的結構:

data 主要是由 URI 和 mimeType 組成的。
URI 可配置很多信息,的結構如下:

與url類似,例如:

mineType:指資源類型包括文本、圖片、音視頻等等,例如:text/plain、 image/jpeg、video/* 等

下面看下data匹配的例子:
只匹配scheme

只匹配scheme也是能匹配到activity的。

匹配scheme、host、port
將上面的data改為

匹配mineType

如果有mineType,則不能僅設置setData或setMineType了,因為setData會把mineType置為null,而setMineType會把data置為null,導致永遠無法匹配到activity,要使用setDataAndType。

使用scheme的默認值contentfile

注意該方法需要在startAtivity方法或者是finish方法調用之後立即執行,不能延遲,但可以在子線程執行。

而在windowAnimationStyle中存在四種動畫:
activityOpenEnterAnimation // 打開新的Activity並進入新的Activity展示的動畫
activityOpenExitAnimation // 打開新的Activity並銷毀之前的Activity展示的動畫
activityCloseEnterAnimation //關閉當前Activity進入上一個Activity展示的動畫
activityCloseExitAnimation // 關閉當前Activity時展示的動畫

overridePendingTransition的方式比較生硬,方法也比較老舊了,不適用於MD風格,google提供了新的轉場動畫ActivityOptions,並提供了兼容包ActivityOptionsCompat。

我們知道在onCreate和onResume裡面直接獲取到控制項寬高為0,那有什麼辦法獲取到控制項的實際寬高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三種方式獲取。

當用戶點擊桌面圖標啟動APP時,背後的流程如下:

我們看到的手機桌面是Launch程序的界面,點擊應用圖標會觸發點擊事件,調用startActivity(intent),然後通過Binder IPC機制,與ActivityManagerService(AMS)通訊,AMS執行一系列操作,最終啟動目前應用,大概流程如下:

通過PackageManager的resolveIntent()收集跳轉intent對象的指向信息,然後通過grantUriPermissionLocked()方法來驗證用戶是否有足夠的許可權去調用該intent對象指向的Activity。如果有許可權,則在新的task中啟動目標activity,如果發現沒有進程,則先創建進程。

如果進程不存在,AMS會調用startProcessLocked創建新的進程,在該方法中,會通過socket的通訊方式通知zygote進程孵化新的進程並返回pid,在新的進程中會初始化ActivityThread,並依次調用Looper.prepareLoop()和Looper.loop()來開啟消息循環。

創建好進程後下一步要將Application和進程綁定起來,AMS會調用上一節創建的ActivityThread對象的bindAppliction方法完成綁定工作,該方法會發送一條BIND_APPLICATION的消息,最終會調用handleBindApplication方法處理消息,並調用makeApplication方法處理消息,載入APP的classes到內存中。

通過前面的步驟,系統已經擁有了該Application的進程,後續的啟動則是從已存在其他進程中啟動Acitivity,即調用realStartAcitvityLocked,該方法會調用Application的主線程對象ActivityThread的sheleLaunchActivity方法,在方法中會發送LAUNCH_ACTIVITY到消息隊列,最終通過handleLaunchActivity處理消息,完成Acitivty的啟動。

Activity
Activity 的 36 大難點,你會幾個?「建議收藏」
[譯]Android Application啟動流程分析

熱點內容
貸款車解壓需要什麼 發布:2024-04-20 13:14:52 瀏覽:70
安卓手機電腦怎麼切換 發布:2024-04-20 13:13:25 瀏覽:891
android交叉編譯環境 發布:2024-04-20 13:00:10 瀏覽:182
伺服器怎麼搭建中間層 發布:2024-04-20 12:40:02 瀏覽:96
如何獲取網路的賬號和密碼 發布:2024-04-20 12:34:06 瀏覽:919
安卓現在哪個品牌用得最久 發布:2024-04-20 12:00:50 瀏覽:276
小拇指演算法 發布:2024-04-20 11:55:28 瀏覽:954
域名查看雲伺服器ip地址 發布:2024-04-20 11:49:17 瀏覽:551
反編譯軟體id 發布:2024-04-20 10:29:49 瀏覽:44
視頻太長怎麼壓縮發微信 發布:2024-04-20 10:00:14 瀏覽:384