Android全面理解Context

2021-07-05 23:51:52 字數 3629 閱讀 9687

context在android中的作用不言而喻,當我們訪問當前應用的資源,啟動乙個新的activity的時候都需要提供context,而這個context到底是什麼呢,這個問題好像很好回答又好像難以說清楚。從字面意思,context的意思是「上下文」,或者也可以叫做環境、場景等,儘管如此,還是有點抽象。從類的繼承來說,

context是乙個抽象基類,我們通過它訪問當前包的資源(getresources、getassets)和啟動其他元件(activity、service、broadcast)以及得到各種服務(getsystemservice),當然,通過context能得到的不僅僅只有上述這些內容。

對context的理解可以來說:context提供了乙個應用的執行環境,在context的大環境裡,應用才可以訪問資源,才能完成和其他元件、服務的互動,context定義了一套基本的功能介面,我們可以理解為一套規範,而activity和service是實現這套規範的子類,這麼說也許並不準確,因為這套規範實際是被contextimpl類統一實現的,activity和service只是繼承並有選擇性地重寫了某些規範的實現。

首先,它們都間接繼承了context,這是它們的相同點。

不同點,可以從幾個方面來說:首先看它們的繼承關係

activity的繼承關係

下面來看一下三者在context方面的區別

activity物件中contextimpl的建立

**為activitythread中的performlaunchactivity方法 if

(activity != 

null

)   

...  

}  

可以看出,activity在建立的時候會new乙個contextimpl物件並在attach方法中關聯它,需要注意的是,建立activity使用的資料結構是activityclientrecord。

public

boolean

instrumentation instrumentation)   

;  if

null

))   

try catch

(exception e)   

}  ...  

}  

看**發現和activity中contextimpl的建立是相同的。

service物件中contextimpl的建立

很明確,不同的context得到的都是同乙份資源。這是很好理解的,請看下面的分析

得到資源的方式為context.getresources,而真正的實現位於contextimpl中的getresources方法,在contextimpl中有乙個成員 private resources mresources,它就是getresources方法返回的結果,mresources的賦值**為:

mresources = mresourcesmanager.gettoplevelresources(mpackageinfo.getresdir(),

display.default_display, null, compatinfo, activitytoken);

下面看一下resourcesmanager的gettoplevelresources方法,這個方法的思想是這樣的:在resourcesmanager中,所有的資源物件都被儲存在arraymap中,首先根據當前的請求引數去查詢資源,如果找到了就返回,否則就建立乙個資源物件放到arraymap中。有一點需要說明的是為什麼會有多個資源物件,原因很簡單,因為res下可能存在多個適配不同裝置、不同解析度、不同系統版本的目錄,按照android系統的設計,不同裝置在訪問同乙個應用的時候訪問的資源可以不同,比如drawable-hdpi和drawable-xhdpi就是典型的例子。

public

resources gettoplevelresources(string resdir, 

intdisplayid,  

configuration overrideconfiguration, compatibilityinfo compatinfo, ibinder token)   

weakreferencewr = mactiveresources.get(key);  

r = wr != null

? wr.get() : 

null

;  //if (r != null) slog.i(tag, "isuptodate " + resdir + ": " + r.getassets().isuptodate());

if(r != 

null

&& r.getassets().isuptodate())   

return

r;  

}  }  

//if (r != null) 

assetmanager assets = new

assetmanager();  

if(assets.addassetpath(resdir) == 

0)   

"resource: key=" + key + ", display metrics=" + metrics);

displaymetrics dm = getdisplaymetricslocked(displayid);  

configuration config;  

boolean

isdefaultdisplay = (displayid == display.default_display);  

final

boolean

hasoverrideconfig = key.hasoverrideconfiguration();  

if(!isdefaultdisplay || hasoverrideconfig)   

if(hasoverrideconfig)   

} else

r = new

resources(assets, dm, config, compatinfo, token);  if(

false

)   

synchronized

(this

)   

// *** need to remove entries when weak references go away

mactiveresources.put(key, new

weakreference(r));  

return

r;  

}  }  

**:單例模式的resourcesmanager類

public

static

resourcesmanager getinstance()   

return

sresourcesmanager;  

}  }  

@override

public

return

(mpackageinfo != 

null

) ?  

}  

Android原始碼分析 全面理解Context

context是乙個抽象基類,我們通過它訪問當前包的資源 getresources getassets 和啟動其他元件 activity service broadcast 以及得到各種服務 getsystemservice 當然,通過context能得到的不僅僅只有上述這些內容。對context的...

Android程式中任意位置獲取Context

context物件在android中是乙個很重要的內容,activity中我們很容易獲得該物件,然後在service以及其他class中並不是那麼簡單。下文介紹如何在任意位置獲得context物件。return instance override public void oncreate 這裡寫上完...

全面理解HTTP

引言 作為一名軟體工程web專業學生,對於http的熟悉掌握是必不可少的,特此做記錄,打造自己的http棧。我們經常接觸到的就是url了,它就是我們訪問web的乙個字串位址,那麼uri是什麼呢?他們是什麼關係呢?url uniform resource location 統一資源定位符 uri un...