如何理解Context?
Context的字面含義是上下文環境。應用的上層代碼通過Context類提供的介面來操作Android的4大組件和資源。在Android的應用程序中,Context無處不在,很多介面都要求用Context對象作為參數。
Android的應用本質上是一個4大組件加上資源文件的容器,但是,這些組件的使用方式各不相同,而且比較複雜,Context類的作用就是把這些細節都封裝起來,這樣更方便開發人員使用它們。因此,可以把Context看作是整個框架的操作介面。
在Android應用中,從Context中派生的類的關係如下:
Context是一個抽象類,定義了介面,它的實現類是ContextImpl類。
ContextWrapper是Context的派生類,它實現了Context類的介面。但是ContextWrapper類所有方法的實現只是轉調其成員變數mBase的方法。mBase本身也是Context對象,其類型是ContextImpl,因此,ContextImpl類才是Context類真正的實現。這種設計模式稱為代理模式或包裝者模式。這種設計模式的好處是把介面和實現分離,可以動態地切換多種實現。
ContextImpl類是Context的真正實現類,它集成了應用框架的一些核心對象,如ActivityThread對象。
Activity,Service,Application都是從ContextWrapper類派生出來的。Activity是通過ContextThemeWrapper類間接派生的,這樣實現的目的是為了實現Activity中單獨的Theme。一個應用中可以有一套全局的Theme,同時每個Activity還可以有自己的Theme。ContextWrapper類的成員變數中保存Theme資源和Resource資源。這樣它的派生類Activity就能有獨立的Theme。
Application的Context和Activity的Context的區別?
Activity、Service和Application這三種類型的Context都是可以通用的。不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog。出於安全原因的考慮,Android是不允許Activity或Dialog憑空出現的,一個Activity的啟動必須要建立在另一個Activity的基礎之上,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是System Alert類型的Dialog),因此在這種場景下,我們只能使用Activity類型的Context,否則將會出錯。
在應用程序中Context的具體實現子類就是:Activity,Service,Application。那麼Context數量=Activity數量+Service數量+1。Broadcast Receiver,Content Provider並不是Context的子類,他們所持有的Context都是其他地方傳過去的,所以並不計入Context總數。3) ContextWrapper.getBaseContext():用來獲取一個ContextWrapper進行裝飾之前的Context,可以使用這個方法,這個方法在實際開發中使用並不多,也不建議使用。
4) Activity.this:返回當前的Activity實例,如果是UI控制項需要使用Activity作為Context對象,但是默認的Toast實際上使用ApplicationContext也可以。5) getApplication()和getApplicationContext():它們得到的是同一個對象。getApplication()只能在Activity和Service中得到。在BroadcastReciver必須使用getApplicationContext()。------------------------------------------------------------------------------------------
本文原創發佈於公眾號《Android面試專欄》,歡迎搜索關注!也歡迎大家留言投稿!
推薦閱讀:
※Skia圖片解析流程與圖片編碼原理初探
※[譯] 網路請求框架 Retrofit 2 使用入門
TAG:Android |