Andorid Activity的本质是什么
本文我主要通過查看Activity的實現源碼和推測其設計思想的方法來探討一下Android的本質是什么。
Activity恐怖是Android用得最多且是最基本的組件了,估計也是每個學Android的人接觸的第一概念,對于Activity的理解和說法,層出不窮,有人說是一個窗口,有個說是一個活動,但他的本質是什么呢,官方的說法是Activity一個應用程序的組件,它提供一個屏幕來與用戶交互,以便做一些諸如打電話、發郵件和看地圖之類的事情,原話如下:
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.
這句話概括的很好,但我并不認為這就是Activity的本質。
切入主題之前,我們先要了解一下UI系統的職責和原理。所有的圖形界面,無論是什么UI系統,都要收集用戶的活動,這些活動包括打開和關閉程序,輸入事件等,這樣系統才能針對這些活動做出一些反應,比如程序打開時加載一個數據庫,建立一個網絡連接,不過針對這些活動所作出的反應都委托給了具體的應用程序,系統相當于只是把這些事件或消息轉發給應用程序。下面是一個簡單的圖:
這些消息怎么轉發給程序呢,可以約定好,要求應程序寫一個方法,或如果是C可要求傳入一個回調,Java可以要求程序傳入一個監聽器,總之實現這個功能還是很容易的,但這么多消息,全部傳到一個方法里嗎,我想那樣會很慘,那樣可能要求你寫應用程序的時候可能要寫一個長長的swich語句或if語句,所以一般都把這些消息分類,如一種是整個程序的活動的消息,如關閉和打開,還有就是輸入事件,如按鍵鼠標,每個分類里的消息還可以再細分,這樣的話,就可以封裝成多個類或接口,每個類有數個方法,之后應用程序重寫這些類方法或實現某個接口,系統就可以通過調用這些類或接口的實例發送消息了。
于是問題轉化成了類的設計。在Windows中,有個窗口類來接受一個窗口的活動,系統就可以通過調用窗口類的方法來傳遞消息,這個窗口類既接受打開和關閉的活動,又接受用戶輸入事件。而在Android中而不同,Activity只接受打開和關閉等的活動,而不會接受輸入事件,那是由Activity內嵌的Window類來接受的,然后轉發給相應View,你有可能會說Activity中有個onKeyDown方法,其實那只是處理沒人領的按鍵消息才會到達Activity。現在發現Android和Windows分發消息的的區別了吧,這樣化分,每個類的職責更細了,更明確了,當然嘍,Android中的消息跟Windows中的可能有點稍小的區別。
現在應該可以很容易的理確Android的每一個生命周期對應的方法(onCreate, onStart...)其實是處理收到的消息,當用戶打開一個Activity的時候,系統(嚴格的說應該是ActivityManager)就會調用onCreate來告訴你這個消息,這個時候你就要加載你的XML布局文件并做一些初始化。然后離開的時候,就應該把這個Activity銷毀嗎,如果用戶是暫時離開,等下還要回來呢,如果銷毀了那就又得重創建,太浪費時間了(用我們家鄉話說就是太難費神了),所以不能銷毀,但是系統也得通知你用戶離開了(用的是onStop方法),因為可能需要暫停播放視頻。當下次重新進入的時候,系統又會通知你用戶又進來了,這時你可能要恢復播放了,但你有沒有發現,用戶第一次進入和再次進入,你需要做不同的處理,第一次可能是初始化一些資源,第二次可能只要恢復播放就可以了,所以系統應該告訴你,是第一次進入還是再次進入,于是系統就用了兩個方法,用onCreate告訴你用戶是第一次進入的,用onStart告訴你用戶是再次進入。
不過這還不算完,還有一種情況,用戶是半離開狀態,什么是半離開呢,都知道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
總結
以上是生活随笔為你收集整理的Andorid Activity的本质是什么的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站建设中百度快照劫持是什么?劫持百度快
- 下一篇: 大势至USB端口管理软件网络版8.1注册