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。
instrumentation instrumentation)
} 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, int displayid,
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類
Android原始碼分析 Activity的啟動過程
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!是android中乙個很重要的概念,堪稱四大元件之首,關於activity有很多內容,比如生命週期和啟動flags,這二者想要說清楚,恐怕又要寫兩篇長文,更何況分析它們的原始碼呢。不過本文的側重點不是它們,我要介紹的是乙個activity典型的啟動...
Android 訊息機制原始碼分析
threadlocal 乙個執行緒內部的資料儲存類,可以在指定執行緒中儲存資料,資料儲存以後,只有在指定執行緒中可以獲取到儲存的資料。先看下以下 主要是重寫了initialvalue方法 請看下面的原始碼 test public void test abc system.out.println th...
android 執行緒池原始碼分析
一直覺得這塊比較複雜,原因在於需要對資料結構和多執行緒開發比較熟悉。現在從threadpoolexecutor 出發。先看這個建構函式。public threadpoolexecutor int corepoolsize,int maximumpoolsize,long keepalivetime,...