寫這篇部落格之前,我内心是有些猶豫的,因為不知道能不能對Android 裡面的源代碼進行細緻的分析,但由于最近幾天,一直在思考,之前學習Android 的路線,無外乎就是完成一些Android 的一些功能,以及Android UI上的一些改動。似乎好像,還沒有認真仔細的去研讀Android的源代碼,總是走馬觀花,不夠耐心。現在做一個小嘗試,開始細心研究Android源代碼,算是我Android 道路上的一個轉折點吧,從此篇部落格開始,以後陸陸續續更新我對Android 源代碼的一些細緻分析了解,并以此篇部落格為證!!!開始我的Android 新篇章!
話不多說,開始今天Android 源代碼的分析!
在Android系統中,我們會經常通過Context擷取系統級别的服務,如WindowsManagerService,ActivityManagerService等,更常用的是一個LayoutInflater的類,這些服務都是以單例的形式注冊在系統中,在我們需要的時候就會通過Context.getSystemService(String name)擷取,我們先就以LayoutInflater為例來說明。
View view = LayoutInflater.from(activity).inflate(layoutResId, guideLayout, false);
我們或多或少都寫過這一段代碼,在ListView的getView的方法中會經常用到,以及在别的地方,加載資源檔案給自定義的View上時,也會用到。
現在就開始一段一段分析:
1.LayoutInflater.from(activity)該方法進去一看Android 的源碼
/**
* Obtains the LayoutInflater from the given context.
*/
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
進入源碼中,我們就會看到LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 這樣一行代碼!
我們再來分析Context這個類中的getSystemService()方法,就得去Context該類中探探究竟了!
* up-calls for application-level operations such as launching activities,
* broadcasting and receiving intents, etc.
*/
public abstract class Context {
/**
* File creation mode: the default mode, where the created file can only
* be accessed by the calling application (or all applications sharing the
* same user ID).
*/
public static final int MODE_PRIVATE = ;
/**
* File creation mode: allow all other applications to have read access to
* the created file.
* <p>
* As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
* mode will throw a {@link SecurityException}
進入Context中,我們首先會發現,這是個抽象類,記得曾經有人說過,抽象類就要去看抽象方法,一般隻有抽象方法需要子類去繼承實作的方法,會顯得很重要!
果然Context.getSystemService()是個抽象方法,以源代碼為例:
* @see android.app.usage.NetworkStatsManager
* @see android.os.HardwarePropertiesManager
* @see #HARDWARE_PROPERTIES_SERVICE
*/
public abstract Object getSystemService(@ServiceName @NonNull String name);
/**
* Return the handle to a system-level service by class.
* <p>
既然這個getSystemService()是個Context抽象類中的抽象方法,那麼我們就得去看Context的實作類去看看該方法是怎麼實作的,Let’s Go!
/**
* Common implementation of Context API, which provides the base
* context object for Activity and other application components.
*/
class ContextImpl extends Context {
private final static String TAG = "ContextImpl";
private final static boolean DEBUG = false;
/**
* Map from package name, to preference name, to cached preferences.
*/
@GuardedBy("ContextImpl.class")
private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache;
/**
* Map from preference name to generated path.
*/
@GuardedBy("ContextImpl.class")
private ArrayMap<String, File> mSharedPrefsPaths;
final ActivityThread mMainThread;
final LoadedApk mPackageInfo;
從這段代碼中,我們可以看出ContextImpl類是Context的實作類,那麼我們就去找找,他的getSystemService()的實作吧!
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return SystemServiceRegistry.getSystemServiceName(serviceClass);
}
該類中有兩個方法,一個擷取系統服務對象,一個擷取系統服務對象的名稱,但這都不是重點,重點是又進入另一個類中的getSystemService()方法中!
return SystemServiceRegistry.getSystemService(this, name);
現在就去SystemServiceRegistry該類看看吧!
/**
* Manages all of the system services that can be returned by {@link Context#getSystemService}.
* Used by {@link ContextImpl}.
*/
final class SystemServiceRegistry {
private final static String TAG = "SystemServiceRegistry";
// Service registry information.
// This information is never changed once static initialization has completed.
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
private static int sServiceCacheSize;
// Not instantiable.
private SystemServiceRegistry() { }
從Android 源代碼中發現該類是一個final 類,終于知道getSystemService()方法的具體實作肯定的在這個類中完成!
我們先看看該類的類結構:
看到該類中有getSystemService()的具體實作,不過我們先不急,先看看整個類的架構,發現其中有一個ServiceFetcher接口以及它的三個實作類,還有一個static 代碼塊,以及一些方法以及兩個HashMap的Field屬性。
先看看static 代碼塊吧:
// Not instantiable.
private SystemServiceRegistry() { }
static {
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class,
new CachedServiceFetcher<CaptioningManager>() {
@Override
public CaptioningManager createService(ContextImpl ctx) {
return new CaptioningManager(ctx);
}});
registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
new CachedServiceFetcher<AccountManager>() {
@Override
public AccountManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});
檢視該靜态代碼塊,是因為靜态代碼塊,第一次加載該類時執行(而且隻會執行一次,保證了執行個體的唯一性),其次就是我們會發現static 代碼塊中有很多個這樣的方法:
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
public AccessibilityManager createService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
隻是參數不同,第一個參數 就是服務的String值,第二個參數,該服務牽扯到的類名,第三個參數為ServiceFetcher 接口的實作類。
registerService(…)方法的實作
/**
* Statically registers a system service with the context.
* This method must be called during static initialization only.
*/
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
裡面主要是利用HashMap (SYSTEM_SERVICE_NAMES和SYSTEM_SERVICE_FETCHERS)将該系統服務的服務名和serviceFetcher保留到HashMap中。
registerService方法有兩個參數,第一個參數就是服務的名稱,第二個參數就是建立的一個ServiceFetcher對象。這個過程可以這麼了解,為了生産服務,我建立了一個工廠(ServiceFetcher),然後我告訴了工廠怎麼生産這個對象(重載createService()方法)。這樣,當我需要服務的時候,工廠就能夠生産我需要的服務(通過createService()方法)。
registerService方法的引用:
看到這兩張圖,聰明的同學大概一下就猜到registerService()方法的意圖了吧,沒錯就是注冊所有的系統服務,将所有系統提供的XXXManager()注冊之後,然後以供調用!
好,現在去看該類的getSystemService()方法
/**
* Gets a system service from a given context.
*/
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
/**
* Gets the name of the system-level service that is represented by the specified class.
*/
public static String getSystemServiceName(Class<?> serviceClass) {
return SYSTEM_SERVICE_NAMES.get(serviceClass);
}
擷取系統服務的方法中的代碼主要就是,通過SYSTEM_SERVICE_FETCHERS(該HashMap)根據之前儲存進來的系統服務名(name) ,通過該key來擷取之前儲存的ServiceFetcher對象。
return fetcher != null ? fetcher.getService(ctx) : null;
進去fecther.getService(ctx)方法中可以看到
/**
* Base interface for classes that fetch services.
* These objects must only be created during static initialization.
*/
static abstract interface ServiceFetcher<T> {
T getService(ContextImpl ctx);
}
這是一個interface ServiceFetcher該接口中的方法,得去看子類的實作比如
/**
* Override this class when the system service constructor needs a
* ContextImpl and should be cached and retained by that context.
*/
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
private final int mCacheIndex;
public CachedServiceFetcher() {
mCacheIndex = sServiceCacheSize++;
}
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
// Fetch or create the service.
Object service = cache[mCacheIndex];
if (service == null) {
service = createService(ctx);
cache[mCacheIndex] = service;
}
return (T)service;
}
}
public abstract T createService(ContextImpl ctx);
}
因為
if (service == null) {
service = createService(ctx);
cache[mCacheIndex] = service;
}
return (T)service;
是以我們又得去看該類中的一個抽象方法 public abstract T createService(ContextImpl ctx);
而createService恰好該方法的實作在registerService()方法中,進行了初始化,舉個例子
registerService(Context.MEDIA_PROJECTION_SERVICE, MediaProjectionManager.class,
new CachedServiceFetcher<MediaProjectionManager>() {
@Override
public MediaProjectionManager createService(ContextImpl ctx) {
return new MediaProjectionManager(ctx);
}});
因為在這裡實作了ServiceFetcher該接口,是以也就重寫了createService()該方法,是以也就擷取了系統服務,并且具體的怎樣的系統服務,就得看你傳哪個系統服務名(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);),然後在SystemServiceRegistry類中hashMap進行緩存了,并且最終在注冊服務(registerService)中實作ServiceFetcher接口,并且重寫createService()方法,進而就可以擷取系統服務了!
由于部落客第一次寫Android 的源代碼分析,寫的不好的地方,以及排版不好的地方,還請多多見諒,以後一定會優化的!