Android
有一段時間了,一直都只顧着學新的東西,最近發現不少日常用的少的東西竟讓都忘了,趁着這兩天,打算把有關 Activity
的內容以問題的形式梳理出來,也供你們查缺補漏。本文中,我將一改往日寫博客的習慣,全文用
XMind
將全部知識點以思惟導圖的形式呈現,歡迎你們食用~~html
倉庫內容與博客同步更新。因爲我在 稀土掘金
簡書
CSDN
博客園
等站點,都有新內容發佈。因此你們能夠直接關注該倉庫,以避免錯過精彩內容!android
Android
的 activity
到底都有哪些東西?Activity
dialog
,Activity
並不會執行生命週期的方法Activity
的話, 固然就是按照正常的生命週期來執行了onPasue()
-> onPause()
( 不會執行原 Activity
的 onStop()
, 不然上個頁面就不顯示了 )不設置 Activity
的 android:configChanges
時,切屏會從新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次github
設置 Activity
的 android:configChanges="orientation"
時,切屏仍是會從新調用各個生命週期,切橫、豎屏時只會執行一次面試
設置 Activity
的 android:configChanges="orientation|keyboardHidden"
時,切屏不會從新調用各個生命週期,只會執行 onConfigurationChanged
方法算法
注意:還有一點,很是重要,一個 Android
的變動細節!當 API >12
時,須要加入 screenSize
屬性,不然屏幕切換時即便你設置了 orientation
系統也會重建 Activity
!shell
Activity
: onCreate()
---> onStart()
---> onResume()
,Activity
進入運行狀態。onPause()
和 onStop()
, 而開屏時則應該執行 onStart()
onResume()
Activity
退居後臺: 當前 Activity
轉到新的 Activity
界面或按 Home
鍵回到主屏: onPause()
---> onStop()
,進入停滯狀態。Activity
返回前臺: onRestart()
---> onStart()
---> onResume()
,再次回到運行狀態。Activity
退居後臺: 且系統內存不足, 系統會殺死這個後臺狀態的 Activity
,若再次回到這個 Activity
,則會走 onCreate()
--> onStart()
---> onResume()
只須要給咱們的 Activity
配置以下屬性便可。 android:theme="@android:style/Theme.Dialog"
服務器
Activity
只需按返回鍵,咱們寫代碼想退出 activity
直接調用 finish()
方法就行。Activity
收到廣播後,關閉 便可。activity
註冊接受接受廣播的意圖 registerReceiver(receiver, filter)
activity
的廣播 activity finish()
掉finish()
方法 把當前的 Activity
退出Activity
時使用 startActivityForResult
, 而後本身加標誌, 在 onActivityResult
中處理, 遞歸關閉。intent
的 flag
來實現 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
激活一個新的 activity
。Activity
, 那麼系統會把這個 Activity
上面的全部 Activity
幹掉。Activity
配置的啓動模式爲 singleTask
。Activity
Activity
, 就記錄下來。Activity
onPause()
和 onStop()
, 而開屏時則應該執行 onStart()
onResume()
Activity
的主題 ,二是經過覆寫 Activity
的 overridePendingTransition
方法。styles.xml
中編輯代碼 , 添加 themes.xml
文件:在 AndroidManifest.xml
中給指定的 Activity
指定 theme
。overridePendingTransition
方法:overridePendingTransition(R.anim.fade, R.anim.hold)
;runnig
:用戶能夠點擊,activity
處於棧頂狀態。paused
:activity
失去焦點的時候,被一個非全屏的 activity
佔據或者被一個透明的 activity
覆蓋,這個狀態的 activity
並無銷燬,它全部的狀態信息和成員變量仍然存在,只是不可以被點擊。(內存緊張的狀況,這個 activity
有可能被回收)stopped
:這個 activity
被另一個 activity
徹底覆蓋,可是這個 activity
的全部狀態信息和成員變量仍然存在(除了內存緊張)killed
:這個 activity
已經被銷燬,其全部的狀態信息和成員變量已經不存在了。Activity
異常退出的時候 --> onPause()
--> onSaveInstanceState()
--> onStop()
--> onDestory()
onSaveInstanceState()
方法與 onPause
並無嚴格的前後關係,有可能在 onPause
以前,也有可能在其後面調用,但會在 onStop()
方法以前調用Activity
--> onCreate()
--> onStart()
--> onRestoreInstanceState()
--> onResume()
Activity
仍是說直接退出整個 app
onSaveInstanceState()
中進行保存數據並在 onRestoreInstanceState()
中進行恢復app
的話就要捕獲全局的異常信息,並退出 app
UncaughtExceotionHandler
來捕獲全局異常進行退出 app
的操做,這樣會減小以前崩潰所形成的後遺症!若是 IntentActivity
處於任務棧的頂端,也就是說以前打開過的 Activity
,如今處於 onPause
、 onStop
狀態的話,其餘應用再發送 Intent
的話網絡
執行順序爲:onNewIntent
,onRestart
,onStart
,onResume
。
Activity
一共有四種 launchMode
:standard
、singleTop
、singleTask
、singleInstance
。Standard
模式(默認模式)說明: 每次啓動一個 Activity
都會又一次建立一個新的實例入棧,不管這個實例是否存在。
生命週期:每次被建立的實例 Activity
的生命週期符合典型狀況,它的 onCreate
、onStart
、onResume
都會被調用。
舉例:此時 Activity
棧中以此有 A
、B
、C
三個 Activity
,此時C處於棧頂,啓動模式爲 Standard
模式。若在 C Activity
中加入點擊事件,需要跳轉到還有一個同類型的 C Activity
。結果是還有一個 C Activity
進入棧中,成爲棧頂。
SingleTop
模式(棧頂複用模式)說明:分兩種處理狀況:需要建立的 Activity
已經處於棧頂時,此時會直接複用棧頂的 Activity
。不會再建立新的 Activity
;若需要建立的 Activity
不處於棧頂,此時會又一次建立一個新的 Activity
入棧,同 Standard
模式同樣。
生命週期:若狀況一中棧頂的 Activity
被直接複用時,它的 onCreate
、onStart
不會被系統調用,因爲它並無發生改變。但是一個新的方法 onNewIntent
會被回調( Activity
被正常建立時不會回調此方法)。
舉例:此時 Activity
棧中以此有 A
、B
、C
三個 Activity
,此時 C
處於棧頂,啓動模式爲 SingleTop
模式。狀況一:在 C Activity
中加入點擊事件,需要跳轉到還有一個同類型的 C Activity
。結果是直接複用棧頂的 C Activity
。狀況二:在 C Activity
中加入點擊事件,需要跳轉到還有一個 A Activity
。結果是建立一個新的 Activity
入棧。成爲棧頂。
SingleTask
模式(棧內複用模式)說明:若需要建立的 Activity
已經處於棧中時,此時不會建立新的 Activity
,而是將存在棧中的 Activity
上面的其餘 Activity
全部銷燬,使它成爲棧頂。
若是是在別的應用程序中啓動它,則會新建一個 task
,並在該task中啓動這個 Activity
,singleTask
容許別的 Activity
與其在一個 task
中共存,也就是說,若是我在這個 singleTask
的實例中再打開新的 Activity
,這個新的 Activity
仍是會在 singleTask
的實例的 task
中。
生命週期:同 SingleTop
模式中的狀況一一樣。僅僅會又一次回調 Activity
中的 onNewIntent
方法
舉例:此時 Activity
棧中以此有 A
、B
、C
三個 Activity
。此時 C
處於棧頂,啓動模式爲 SingleTask
模式。狀況一:在 C Activity
中加入點擊事件,需要跳轉到還有一個同類型的 C Activity
。結果是直接用棧頂的 C Activity
。狀況二:在 C Activity
中加入點擊事件,需要跳轉到還有一個 A Activity
。結果是將 A Activity
上面的 B
、C
全部銷燬,使 A Activity
成爲棧頂。
SingleInstance
模式(單實例模式)說明: SingleInstance
比較特殊,是全局單例模式,是一種增強的 SingleTask
模式。它除了具備它全部特性外,還增強了一點:只有一個實例,而且這個實例獨立運行在一個 task
中,這個 task
只有這個實例,不容許有別的 Activity
存在。
這個常用於系統中的應用,好比 Launch
、鎖屏鍵的應用等等,整個系統中僅僅有一個!因此在咱們的應用中通常不會用到。瞭解就能夠。
舉例:比方 A Activity
是該模式,啓動 A
後。系統會爲它建立一個單獨的任務棧,因爲棧內複用的特性。興許的請求均不會建立新的 Activity
,除非這個獨特的任務棧被系統銷燬。
Manifest.xml
中指定 Activity
啓動模式Manifest.xml
文件裏聲明 Activity
的同一時候指定它的啓動模式Activity
。Activity
時。在 Intent
中指定啓動模式去建立 Activity
new
一個 Intent
後Intent
的 addFlags
方法去動態指定一個啓動模式。Activity
指定啓動模式,但是兩者仍是有差異的。優先級:動態指定方式即另一種比第一種優先級要高,若二者同一時候存在,以另一種方式爲準。
限定範圍:第一種方式沒法爲 Activity
直接指定 FLAG_ACTIVITY_CLEAR_TOP
標識,另一種方式沒法爲 Activity
指定 singleInstance
模式。
這四種模式中的
Standard
模式是最普通的一種,沒有什麼特別注意。而SingleInstance
模式是整個系統的單例模式,在咱們的應用中通常不會應用到。因此,這裏就具體解說SingleTop
和SingleTask
模式的運用場景:
SingleTask
模式的運用場景Activity
的實例。Home
頁)。SingleTask
模式,在點擊返回的過程當中會屢次看到主頁,這明顯就是設計不合理了。SingleTop
模式的運用場景Activity
中又要啓動同類型的 Activity
Activity
的啓動模式指定爲 SingleTop
,可以下降Activity的建立,節省內存!Activity
時的生命週期回調Activity
跳轉時攜帶頁面參數的問題。Activity
設置了 SingleTop
或者 SingleTask
模式後,跳轉此 Activity
出現複用原有 Activity
的狀況時,此 Activity
的 onCreate
方法將不會再次運行。onCreate
方法僅僅會在第一次建立 Activity
時被運行。onCreate
方法中會進行該頁面的數據初始化、UI
初始化,假設頁面的展現數據無關頁面跳轉傳遞的參數,則沒必要操心此問題getInten()
方法來獲取,那麼問題就會出現:getInten()
獲取的一直都是老數據,根本沒法接收跳轉時傳送的新數據!以上代碼中的 CourseDetailActivity
在配置文件裏設置了啓動模式是 SingleTop
模式,依據上面啓動模式的介紹可得知,當 CourseDetailActivity
處於棧頂時。
再次跳轉頁面到 CourseDetailActivity
時會直接複用原有的 Activity
,而且此頁面需要展現的數據是從 getIntent()
方法得來,但是 initData()
方法不會再次被調用,此時頁面就沒法顯示新的數據。
固然這樣的狀況系統早就爲咱們想過了,這時咱們需要另一個回調 onNewIntent(Intent intent)
方法。此方法會傳入最新的 intent
,這樣咱們就可以解決上述問題。這裏建議的方法是又一次去 setIntent
。而後又一次去初始化數據和 UI
。代碼例如如下所看到的:
Activity
的 onCreate
方法中執行過多繁重的操做,而且在 onPasue
方法中一樣不能作過多的耗時操做。注意!這裏並非要回答 Activity
的生命週期!
標記位既可以設定Activity的啓動模式,如同上面介紹的,在動態指定啓動模式,比方 FLAG_ACTIVITY_NEW_TASK
和 FLAG_ACTIVITY_SINGLE_TOP
等。它還可以影響 Activity
的運行狀態 ,比方 FLAG_ACTIVITY_CLEAN_TOP
和 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
等。
如下介紹幾個基本的標記位,切勿死記,理解幾個就能夠,需要時再查官方文檔。
FLAG_ACTIVITY_NEW_TASK
Activity
指定 「SingleTask」
啓動模式。跟在 AndroidMainfest.xml
指定效果一樣FLAG_ACTIVITY_SINGLE_TOP
Activity
指定 「SingleTop」
啓動模式,跟在 AndroidMainfest.xml
指定效果一樣。FLAG_ACTIVITY_CLEAN_TOP
Activity
,啓動時會將與該 Activity
在同一任務棧的其餘 Activity
出棧。SingleTask
啓動模式一塊兒出現。SingleTask
的做用。SingleTask
啓動模式默認具備此標記位的做用FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
Activity
不會出現在歷史 Activity
的列表中Activity
時,此標記位便體現了它的效果。xml
中指定 Activity
的屬性.這個是啓動模式中的了,當此 Activity
的實例已經存在,而且此時的啓動模式爲 SingleTask
和 SingleInstance
,另外當這個實例位於棧頂且啓動模式爲 SingleTop
時也會觸發 onNewInstent()
。
Intent
在傳遞數據時是有大小限制的,這裏官方並未詳細說明,不過經過實驗的方法能夠測出數據應該被限制在 1MB
以內( 1024KB
)Bitmap
的方法,發現當圖片大小超過 1024
(準確地說是 1020
左右)的時候,程序就會出現閃退、中止運行等異常(不一樣的手機反應不一樣)Intent
的傳輸容量在 1MB
以內。Activity
的 onSaveInstanceState()
和 onRestoreInstanceState()
並非生命週期方法,它們不一樣於 onCreate()
、onPause()
等生命週期方法,它們並不必定會被觸發。
onSaveInstanceState()
方法,當應用遇到意外狀況(如:內存不足、用戶直接按 Home
鍵)由系統銷燬一個 Activity
,onSaveInstanceState()
會被調用。
可是當用戶主動去銷燬一個 Activity
時,例如在應用中按返回鍵,onSaveInstanceState()
就不會被調用。
除非該 activity
不是被用戶主動銷燬的,一般 onSaveInstanceState()
只適合用於保存一些臨時性的狀態,而 onPause()
適合用於數據的持久化保存。
HOME
後要運行多少其餘的程序,天然也不知道 activity A
是否會被銷燬onSaveInstanceState()
,讓用戶有機會保存某些非永久性的數據。如下幾種狀況的分析都遵循該原則:HOME
鍵時HOME
鍵,選擇運行其餘的程序時activity A
中啓動一個新的 activity
時通常狀況下好比說有兩個 activity
, 分別叫 A
, B
,當在 A
裏面激活 B
組件的時候, A
會調用 onPause()
方法,而後 B
調用 onCreate()
, onStart()
, onResume()
。
這個時候 B
覆蓋了窗體, A
會調用 onStop()
方法. 若是 B
是個透明的,或者 是對話框的樣式, 就不會調用 A
的 onStop()
方法。
adb shell am
命令am
啓動一個 activity
adb shell am start com.example.fuchenxuan/.MainActivity
am
發送一個廣播,使用 action
adb shell am broadcast -a magcomm.action.TOUCH_LETTER
服務器能夠定製化跳轉 app
頁面
app
能夠經過 Scheme
跳轉到另外一個 app
頁面
能夠經過 h5
頁面跳轉 app
原生頁面
qh
表明 Scheme
協議名稱
test
表明 Scheme
做用的地址域
8080
表明改路徑的端口號
/goods
表明的是指定頁面(路徑)
goodsId
和 name
表明傳遞的兩個參數
Scheme
Scheme
跳轉的參數Activity
和 Application
都是 Context
的子類。Context
從字面上理解就是上下文的意思, 在實際應用中它也確實是起到了管理 上下文環境中各個參數和變量的總用, 方便咱們能夠簡單的訪問到各類資源。Context
維護的是當前的 Activity
的生命週期, Application
維護的是整個項目的生命週期。context
的時候, 當心內存泄露, 防止內存泄露它描述的是一個應用程序環境的信息,即上下文。
該類是一個抽象( abstract class
)類, Android
提供了該抽象類的具體實 現類( ContextIml
)。
經過它咱們能夠獲取應用程序的資源和類, 也包括一些應用級別操做, 例如:啓動一個 Activity
,發送廣播,接受 Intent
,信息,等。
使用 ActivityLifecycleCallbacks
面試官問這個問題,想看看你們對Activity瞭解是否深刻:
activity
。activity
是 Context
的子類,同時實現了 window.callback
和 keyevent.callback
,能夠處理與窗體用戶交互的事件。FragmentActivity
、ListActivity
、TabActivity
( Android 4.0
被 Fragment
取代)Activity
( onResume()
)Service
綁定正在交互的 Activity
Service
( startForeground()
)onCreate()
、onStart()
、onDestory()
)BroadcastReceiver
正在執行 onReceive()
Activity
處在 onPause()
(沒有進入 onStop()
)Activity
的 Service
startService()
啓動。Activity
處於 onStop()
的時候。android:process=":xxx"
Android
設計的,處於緩存的目的,爲了第二次啓動更快,採起的一個權衡)可見進程指部分程序界面可以被用戶看見,卻不在前臺與用戶交互的進程。例如,咱們在一個界面上彈出一個對話框(該對話框是一個新的
Activity
),那麼在對話框後面的原界面是可見的,可是並無與用戶進行交互,那麼原界面就是可見進程。
onPause()
方法已經被調用)。舉例來講,這可能發生在,若是一個前臺活動在一個對話框(其餘進程的)運行以後仍然是可視的,好比輸入法的彈出時。服務進程是經過 startService()
方法啓動的進程,但不屬於前臺進程和可見進程。例如,在後臺播放音樂或者在後臺下載就是服務進程。
系統保持它們運行,除非沒有足夠內存來保證全部的前臺進程和可視進程。
Activity
對象的 onStop()
方法)(若是還有除了 UI
線程外其餘線程在運行話,不受影響)。例如我正在使用
Home
鍵讓
LRU
( least recently used
,即最近最少使用,若是您學過操做系統的話會以爲它很熟悉,跟內存的頁面置換算法 LRU
同樣)列表以確保最近使用最多的活動的進程最後被殺。空進程是一個沒有保持活躍的應用程序組件的進程,不包含任何活躍組件。
保持這個進程可用的惟一緣由是做爲一個 cache
以提升下次啓動組件的速度。系統進程殺死這些進程,以在進程 cache
和潛在的內核 cache
之間平衡整個系統資源。
android
進程的回收順序從先到後分別是:空進程,後臺進程,服務進程,可見進程,前臺進程。
ANR
,全稱爲 Application Not Responding
。Android
中,若是你的應用程序有一段時間沒有響應,系統會向用戶顯示一個對話框,這個對話框稱做應用程序無響應對話框。ANR
給用戶。ANR
的時間不同,主線程( Activity
、Service
)是 5
秒,BroadCastReceiver
是 10
秒。Socket
通訊,查詢大量 SQL
語句,複雜邏輯計算等都放在子線程中去,而後經過 handler.sendMessage
、runonUITread
、AsyncTask
等方式更新 UI
,以確保用戶界面操做的流暢度。Task
包含的就是 activity
集合,android
系統能夠經過任務棧有序的管理 activity
activity
也能夠獨享一個任務棧( singleInstance
模式啓動的 activity
)Android Activity
的全部知識點。對於 App
啓動、AMS
但願你們能根據文中連接或者 Google
搜索的形式繼續展開學習。重點
:關於 Android
的四大組件,到如今爲止我才總結完 Activity ,立刻我將繼續針對,Service
,BroadcastRecevier
等,以及事件分發、滑動衝突、新能優化等重要模塊,進行全面總結,歡迎你們關注 _yuanhao 的 掘金 ,方便及時接收更新因爲我在「稀土掘金」「簡書」「CSDN
」「博客園」等站點,都有新內容發佈。因此你們能夠直接關注個人 GitHub
倉庫,以避免錯過精彩內容!
一萬多字長文,加上精美思惟導圖,記得點贊哦,歡迎關注 _yuanhao 的 掘金 ,咱們下篇文章見!