Android原始碼分析 全面理解Context

2021-07-12 03:20:41 字數 3334 閱讀 6871

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