Android之Context底層原理
1.Context基本概念
Context的中文翻譯為:語境; 上下文; 背景; 環境,在開發中我們經常說稱之為“上下文”。從Android系統的角度來理解:Context是一個場景,代表與作業系統的互動的一種過程。Context在載入資源、啟動Activity、獲取系統服務、建立View等操作都要參與 。從程式的角度上來理解:Context是個抽象類,而Activity、Service、Application等都是該類的一個實現。
2.Context與Activity、Service、Application關係
Context類本身是一個純abstract類,他有兩個具體的實現子類:ContextImpl和ContextWrapper。其中ContextWrapper類,只是一個包裝而已,ContextWrapper建構函式中必須包含一個真正的Context引用,同時ContextWrapper提供了attachBaseContext()用於給ContextWrapper物件中指定真正的Context物件,呼叫ContextWrapper的方法都會被轉向其所包含的真正的Context物件。
ContextThemeWrapper類,其內部包含了與主題(Theme)相關的介面,這裡所說的主題就是指在AndroidMainifest.xml中通過android:theme為Application元素或者Activity元素指定的主題。當然,只有Activity才需要主題,Service是不需要主題的,Application同理。
而ContextImpl類則真正實現了Context中的所有函式,應用程式中所呼叫的各種Context類的方法,其實現均來於該類。Context的兩個子類分工明確,其中ContextImpl是Context的具體實現類,ContextWrapper是Context的包裝類。
3.Context作用域
Activity的作用域最廣,Application和Service在啟動Activity需要建立一個新的task,一般不推薦。layout infalte也是合法的,但是會使用系統預設的主題樣式,如果自定義某些樣式可能不會被使用
4.Context的使用
4.1Context的數量
一個應用程式中到底有多少個Context呢?根據Context的型別可以得出,一共有Application、Activity和Service三種型別,因此一個應用程式的Context數量為:
Context數量=Activity數量+Service數量+1
4.2如何獲取Context
1)View.getContext,返回當前Activity所在的應用程式的Context物件,通常是當前正在展示的Activity物件
2)Activity.getApplicationContext,獲取當前Activity所在的(應用)程式的Context物件,通常我們使用Context物件時,要優先考慮這個全域性的程式Context。
3)Activity.this返回當前的Activity例項,如果是UI控制元件需要使用Activity作為Context物件,但是預設的Toast因為是系統層級的Windows,直接使用ApplicationContext則可。
4)getApplication和getApplicationContext獲取的物件時一致的。但是getApplication方法只有在Activity和Service中才能調到。但例如BroadcasrReceiver中需要獲取Application,則需要藉助getApplicationContext()方法。
4.3Context引起的內測洩漏
1)錯誤的單例模式
即使Activity被銷燬掉,但因為它的引用還存在於一個Singleton中,就不可能被GC掉
2)View持有Activity引用
有一個靜態的Drawable物件當ImageView設定這個Drawable時,ImageView儲存了mDrawable的引用,而ImageView傳入的this是MainActivity的mContext,因為被static修飾的mDrawable是常駐記憶體的,MainActivity是它的間接引用,MainActivity被銷燬時,也不能被GC掉,所以造成記憶體洩漏。
5.總結
1)儘量使用Application的Context
2)不要讓生命週期長於Activity的物件持有其的引用
3)儘量不要在Activity中使用非靜態內部類,因為非靜態內部類會隱式持有外部類示例的引用,如果使用靜態內部類,將外部例項引用作為弱引用持有
相關文章
- php底層原理之函式PHP函式
- AOP底層原理之CGlibCGLib
- php底層原理之變數(二)PHP變數
- php底層原理之變數(一)PHP變數
- PHP 底層原理之類和物件PHP物件
- 分散式之系統底層原理分散式
- OC底層探索(十六) KVO底層原理
- synchronized底層原理synchronized
- php底層原理之垃圾回收機制PHP
- php底層原理之陣列實現PHP陣列
- 面試必備之MYSQL索引底層原理分析面試MySql索引
- RunLoop底層原理探究OOP
- RabbitMq底層原理分析MQ
- HashMap原理底層剖析HashMap
- HashMap的底層原理HashMap
- iOS底層原理-CategoryiOSGo
- ArrayList集合底層原理
- ConcurrentHashMap底層原理HashMap
- HashMap底層實現原理HashMap
- 理解PHP底層原理(一)PHP
- 底層原理面試彙總面試
- 初步理解 JavaScript 底層原理JavaScript
- Netty的底層原理Netty
- Spring Cloud底層原理SpringCloud
- NSDictionary底層實現原理
- Vue中的底層原理Vue
- ArrayList底層原理淺析
- HashMap的底層原理分析HashMap
- 底層原理探究(二)RunLoopOOP
- AutoreleasePool底層實現原理
- iOS底層原理探究-RunloopiOSOOP
- golang select底層原理Golang
- InnoDB索引與底層原理索引
- Volatile的底層原理
- OC底層原理之例項、類物件、元類物件物件
- iOS底層原理總結 – RunLoopiOSOOP
- [譯] SQLite 底層查詢原理SQLite
- volatile底層原理詳解