本文我主要經過查看Activity的實現源碼和推測其設計思想的方法來探討一下Android的本質是什麼。
html
Activity恐怖是Android用得最多且是最基本的組件了,估計也是每一個學Android的人接觸的第一律念,對於Activity的理解和說法,層出不窮,有人說是一個窗口,有個說是一個活動,但他的本質是什麼呢,官方的說法是Activity一個應用程序的組件,它提供一個屏幕來與用戶交互,以便作一些諸如打電話、發郵件和看地圖之類的事情,原話以下:java
An Activity
is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map.
android
這句話歸納的很好,但我並不認爲這就是Activity的本質。數據庫
切入主題以前,咱們先要了解一下UI系統的職責和原理。全部的圖形界面,不管是什麼UI系統,都要收集用戶的活動,這些活動包括打開和關閉程序,輸入事件等,這樣系統才能針對這些活動作出一些反應,好比程序打開時加載一個數據庫,創建一個網絡鏈接,不過針對這些活動所做出的反應都委託給了具體的應用程序,系統至關於只是把這些事件或消息轉發給應用程序。下面是一個簡單的圖:設計模式
這些消息怎麼轉發給程序呢,能夠約定好,要求應程序寫一個方法,或若是是C可要求傳入一個回調,Java能夠要求程序傳入一個監聽器,總之實現這個功能仍是很容易的,但這麼多消息,所有傳到一個方法裏嗎,我想那樣會很慘,那樣可能要求你寫應用程序的時候可能要寫一個長長的swich語句或if語句,因此通常都把這些消息分類,如一種是整個程序的活動的消息,如關閉和打開,還有就是輸入事件,如按鍵鼠標,每一個分類裏的消息還能夠再細分,這樣的話,就能夠封裝成多個類或接口,每一個類有數個方法,以後應用程序重寫這些類方法或實現某個接口,系統就能夠經過調用這些類或接口的實例發送消息了。網絡
因而問題轉化成了類的設計。在Windows中,有個窗口類來接受一個窗口的活動,系統就能夠經過調用窗口類的方法來傳遞消息,這個窗口類既接受打開和關閉的活動,又接受用戶輸入事件。而在Android中而不一樣,Activity只接受打開和關閉等的活動,而不會接受輸入事件,那是由Activity內嵌的Window類來接受的,而後轉發給相應View,你有可能會說Activity中有個onKeyDown方法,其實那只是處理沒人領的按鍵消息纔會到達Activity。如今發現Android和Windows分發消息的的區別了吧,這樣化分,每一個類的職責更細了,更明確了,固然嘍,Android中的消息跟Windows中的可能有點稍小的區別。app
如今應該能夠很容易的理確Android的每個生命週期對應的方法(onCreate, onStart...)實際上是處理收到的消息,當用戶打開一個Activity的時候,系統(嚴格的說應該是ActivityManager)就會調用onCreate來告訴你這個消息,這個時候你就要加載你的XML佈局文件並作一些初始化。而後離開的時候,就應該把這個Activity銷燬嗎,若是用戶是暫時離開,等下還要回來呢,若是銷燬了那就又得重建立,太浪費時間了(用咱們家鄉話說就是太難費神了),因此不能銷燬,可是系統也得通知你用戶離開了(用的是onStop方法),由於可能須要暫停播放視頻。當下次從新進入的時候,系統又會通知你用戶又進來了,這時你可能要恢復播放了,但你有沒有發現,用戶第一次進入和再次進入,你須要作不一樣的處理,第一次多是初始化一些資源,第二次可能只要恢復播放就能夠了,因此係統應該告訴你,是第一次進入仍是再次進入,因而系統就用了兩個方法,用onCreate告訴你用戶是第一次進入的,用onStart告訴你用戶是再次進入。ide
不過這還不算完,還有一種狀況,用戶是半離開狀態,什麼是半離開呢,都知道Android的界在有全屏,仍是非全屏,也有半透明的,這裏的半離開指的就是本界面被一個非全屏或半透明的界面蓋住,總之,你還能看到一點點被蓋的那個界面;全離開就是被全屏的界面蓋住,用戶徹底看不到被蓋的。這兩種狀況要有可能要區別對待,好比一個播放在線視頻的應用,它可能但願要在用戶半離開時只暫停播放,不暫停後臺下載,而當用戶徹底離開時,播放和下載都暫停。因此係統也應該區分這種狀況,因而就有了onPause和onResume來表示半離開和從半離開恢復。值得注意的是,Android中全離開包括了半離開,半離開不包括全離開,什麼意思呢,就是即使是全離開,系統也是先調onPause再調onStop,從全離開中恢復,也是調了onStart後還會調onResume,而對於第一次進入,onCreate、onStart、onResume會被依次調用,因此記住,只要用戶進入,不管是怎麼進入的,都是調用onResume,在這裏恢復播放是再適合不過的了。還有一個onDestory也說一下,就是在銷燬的時候被調用,通常是回收資源或按了返回鍵會被銷燬。如今清楚了,也順便看一下Android官網的這張圖吧:函數
而後,你可能好奇系統是怎麼調用到你寫的onCreate方法的,有興趣的能夠查看源碼的frameworks/base/core/java/android/app/ActivityThread.java,此類裏面有許多handle***Activity方法,如handleResumeActivity,不過這不是本文章討論的重點,後續有可能另寫一篇討論。佈局
下面咱們來討論一下Activity這個類吧,我估計不少人都忽略了Activity類也是一個類,它也能夠有構造函數,你還能夠在構造函數裏初始化一些東西,不過請注意,Activity的onDestroy被調用時,Activity這個類自己尚未被銷燬。還一點也不多人忽略,我常問應聘者Activity之間怎麼通訊,他們通常都會說Intent或AIDL,若是兩個Activity是同一個應用的,通常是運行在同一進程中的(除非你在AndroidManifest裏配置了讓它們不運行在同一進程),並且通常是同一線程的,因此最簡單的通訊方法,莫過於在A Activity中寫一個方法,讓B Activity來調用,你再懶一點,直接訪問變量均可以,只是風格很差。
其它,還要說明的是,一個Activity包含了一個Window,Window纔是真正表明一個窗口,也就是說Activity能夠沒有Window,那正好是Service了,論據就是剛剛說的ActivityThread類,他的職責包括處理Service,(ActivityThread不是Thread的子類,但他描述了主線程要作的事,具體本文暫不討論)。Window包含了一個DecorView,這纔是真正的界面元素,它是整個View樹的根,你能夠試試在Activity裏調用下面這句代碼把整個界面染紅:
getWindow().getDecorView().setBackgroundColor(Color.RED);
另外,還有一個ViewRoot,這個和DecorView常常有人搞混,首先是它對應的類的真正名字是ViewRootImpl,而後,他不是一個View,即他不是View的子類,他的工做與視覺元素無直接關係,但他肯定Android View系統的一個重要類,它是負責通訊的,若是你知道bridge設計模式就好理解了,這就是一個活生生的例子啊,不過不知道也不要緊,不會阻礙對下文的理解,負責誰跟誰通訊呢,是負責你的WindowManager與WindowManagerSerivce之間通訊,整個系統的窗口都是由WindowManagerSerivce管理的,由於全部窗口的Z-order,事件分發,都要由一箇中樞統一管理纔可能有秩序,這就是WindowManagerSerivce的職責了。這樣說,你確定不能徹底理解,要理解仍是看代碼吧,路徑:frameworks/base/core/java/android/view/ViewRootImpl.java。其中有一句:
mOrigWindowType = mWindowAttributes.type; res = sWindowSession.add(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mAttachInfo.mContentInsets, mInputChannel);
就是向WindowManagerSerivce註冊了一個輸入事件處理監聽器mInputChannel,具體實現能夠寫一篇很長的文章,暫不討論。
這就是與Activity主要相關的信息,但願本文加深了你對Activity的理解。
參考資料:
官網指南:http://developer.android.com/guide/components/activities.html