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...