當前位置:編程學習大全網 - 源碼下載 - Context是什麽

Context是什麽

? ? Context

? Context,翻譯是上下文環境,在android應用開發中的地位舉足輕重,甚至源碼也有壹句話:everything needs a context(看到過,但是忘了在哪裏了)。

從這個類圖中我們看到,Context是壹個抽象類,壹邊是Context的具體實現ContextImpl,壹邊則是組件的封裝類ContextWrapper,便於二者各司其職,我理解是接口和實現分開,這樣比較符合開閉原則吧。

? 既然要搞清楚Context是幹嘛的,得先看Context的實例什麽時候創建的。這裏有兩個我們經常接觸的組件,Activity和Service,以及用的較少的Application,它們的關系如下:

1.Application:保存應用的全局信息的類,它的實例在應用創建的時候被創建,生命周期最長,應用銷毀了才會被銷毀。

2.Activity:創建壹個Activity便對應壹個Context的實例,生命周期隨著Activity的周期變化。

3.Service:創建壹個Service便對應壹個Context的實例,生命周期隨著Service的周期變化。

下面逐壹看看它們是什麽時候實例Context類的,我們需要知道,壹個ContextWrapper類對應壹個ContextImpl類的實例,因為具體實現的地方還是在ContextImpl中,ContextWrapper中的mBase變量指向ContextImpl變量的實例。

(1) Application的Context創建:

如圖:

跳過Process創建過程,在我們的應用被zygote進程孵化出來後,被反射調用main函數,這裏會創建ActivityThread類的實例,該類並不是壹個線程類的子類,但是它的main函數跑在新創建的進程的主線程。 創建後,調用attach方法,與AMS綁定:

這裏傳入的mAppThread變量為ApplicationThread類,它為ActivityThread的內部類,作用就是作為應用端的binder服務端,負責接收AMS的調度,這裏我們傳入這個服務端的句柄,讓AMS持有,從而AMS可以通過這個句柄來操控應用的行為。我們向AMS請求,則是通過AMS的句柄。接下來就到了AMS的邏輯:

在ApplicationThread的實現端中,就是把跨進程傳遞過來的各種數據再用壹個AppBindData類保存下來,然後調用Handler對象H發送消息BIND_APPLICATION,最後在app線程中處理此邏輯,讓AMS線程可以不必同步阻塞。接下來就到了handleBindApplication:

Instrumentation類是用於管理Acitivty的工具類。這又有壹個比較重要的對象出現,LoadedApk,它裏面保存了類加載器ClassLoader,data.info的對象便是它,makeApplication函數中的邏輯:

? 這裏我們看到了ContextImpl的創建時機,就是在Application實例創建的時候:

? 如此就完成了Application的創建,並且調用attach方法把Application的mBase對象賦值給創建的ContextImpl,至此Application的創建就完成了,getApplicationContext() 返回的便是此處我們創建的Application類的對象。

這裏為什麽要去LoadedApk類中利用類加載器,把對象創建出來呢?因為我們的Application類是可以自己拓展的,創建的時候是不確定應用自己是否復寫了Application對象, 利用類加載器就可以動態決定創建什麽類的對象了 ,我們只需要從PMS中獲取到application的具體類名即可,這個類名是寫在Mainfest文件中的,後面Activity也是利用這種機制去創建對象。

(2)Actvity的啟動過程,網上非常多文章分析了,我也就不再重復羅列出來了,大概的過程就是startActivity()被調用,然後檢查目標Acitivity的進程是否創建,沒創建就先向Zygote進程請求fork應用進程,然後壹系列初始化過程後,最後在AMS模塊中的ActivityStackSupervisor中realStartActivityLocked()調用IApplicationThread代理類,調用到scheduleLaunchActivity(),然後在應用的線程開始執行handleLaunchActivity(),最主要的邏輯在performLaunchActivity:

? 至於Activity的生命周期後面怎麽走的,這裏不在乎,我們只看Context實例化過程。同樣的,這裏也會創建ContextImpl對象,在Activity對象創建後,調用Attach(),這個函數挺重要的,我們看看都幹了什麽:

? 在attach函數中,也會為ContextWrapper中的mBase對象賦值壹個ContextImpl對象,我們這裏也能猜想到Service的創建估計也會有這個過程,而事實上Service的創建差不多也是這個過程,所以不再贅述了。

我們可以知道Context例的實例化都是在我們在Application,Activity和Service創建的時候會實例化,而這些組件的父類都是ContextWrapper,所以在創建的時候還會先創建壹個ContextImpl類對象,然後給自己的父類mBase變量賦值,既然如此,Context的引用對應的就是Application,Activity和Service了,Context的用處就是提供了壹組抽象的函數,讓子類去相對應的實現,當妳持有壹個Context引用的時候,妳可以通過這個引用去獲取相對應組件的信息。比如持有壹個Activity的Context引用,妳可以在別的地方調用startActivity()去啟動壹個新的activity。

總結:

? 1.Context是抽象類,所以實例化要在子類中,Application,Service,Activity是我們實例化的地方,壹般應用創建會實例化壹個Application類,Service和Activity則是在startService和StartActivity被調用的時候會實例化,它們都會創建壹個ContextImpl類實例,給自己的父類ContextWrapper的mBase變量賦值。

? 2.Context是組件中通用操作的壹組集合,當具體的子類實例化後,可以在別的地方通過保存壹個Context引用去獲取信息和通用操作等,也就是說,我們可以通過這個引用去獲取到這個應用中的重要信息以及這個應用的通用操作。

  • 上一篇:c++好學嗎?
  • 下一篇:圓形拼音
  • copyright 2024編程學習大全網