亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Android系統服務是如何獲取的

瀏覽:5日期:2022-09-20 11:10:31
關于獲取系統服務的猜想

Android獲取系統服務一般都需要用getSystemService指定系統服務名稱獲取:

val wm = getSystemService(Context.WINDOW_SERVICE) as WindowManager

在實際開發中,當我們需要編寫提供某一業務流程處理的Manager,通常會實現為單例。那么上面那行代碼背后發生了什么,為什么Android不使用單例模式呢?下面我們觀察Android是如何設計獲取系統服務的,它如何從應用側到達系統側。

可以思考一下,不在每個服務中單獨使用單例的原因大概是因為Android提供的系統服務眾多,都使用getSystemService方法相當于提供了統一的入口。同時因為方法參數中的服務名稱字符串,可以提供一個Map來統一存放各種服務實例,這與單例模式十分接近,相當于統一管理各種單例的變種。那么事實是不是這樣呢?(下方源碼只保留關鍵代碼,API 30)

獲取系統服務源碼實現

各種繼承或者持有Context的組件的getSystemService方法都會調用ContextImpl的同名方法:

//ContextImpl.java public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }

SystemServiceRegistry一看就是統一注冊系統服務的地方:

//SystemServiceRegistry.java public static Object getSystemService(ContextImpl ctx, String name) { final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); final Object ret = fetcher.getService(ctx); return ret; }

這里我們確實發現了Map,可卻不是從String到系統服務的Map,SYSTEM_SERVICE_FETCHERS的類型為Map<String, ServiceFetcher<?>>。

//SystemServiceRegistry.java static abstract interface ServiceFetcher<T> { T getService(ContextImpl ctx); }

這個SystemServiceRegistry中的內部接口ServiceFetcher,看上去像是各種系統服務的工廠接口。我們看它的實現類:

//SystemServiceRegistry.java static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> { private final int mCacheIndex; CachedServiceFetcher() { mCacheIndex = sServiceCacheSize++; } @Override public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; T ret = null; T service = (T) cache[mCacheIndex]; if (service != null) {ret = service; } else {service = createService(ctx);cache[mCacheIndex] = service;ret = service; } return ret; } public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException; }

getService方法精簡了大量保證線程安全的同步措施,只保留了最核心的邏輯。可以看到另有一個類型為Object[]的數組ctx.mServiceCache,getService從中用下標mCacheIndex獲取系統服務,如果服務為空則使用createService方法創建服務并放在數組中。可以說,這個ctx.mServiceCache數組起到了我們最初設想的從String到系統服務的Map的存放所有系統服務的作用。這個映射變為了:

假象的映射(從String到系統服務) <=> SYSTEM_SERVICE_FETCHERS映射(從String到ServiceFetcher) + ctx.mServiceCache數組(ServiceFetcher中的mCacheIndex下標到系統服務)

這個SYSTEM_SERVICE_FETCHERS映射在SystemServiceRegistry的靜態初始化快中被統一填充,同時提供了上方沒有實現的createService:

//SystemServiceRegistry.java static { registerService(Context.WINDOW_SERVICE, WindowManager.class,new CachedServiceFetcher<WindowManager>() { @Override public WindowManager createService(ContextImpl ctx) {return new WindowManagerImpl(ctx); }}); } private static <T> void registerService(@NonNull String serviceName, @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); }

SystemServiceRegistry類初始化時,ctx.mServiceCache系統服務數組還是空的,當某一系統服務需要時,上方CachedServiceFetcher中getService會調用createService創建服務并存放在特定mCacheIndex下標中。

總結一下就是:在Android獲取系統服務的流程中,使用工廠模式創建系統服務,使用Map管理工廠,使用數組管理系統服務實例。每種服務在每個ContextImpl中的數組中最多只有一個,且使用前不會提前創建,這點和單例的懶漢式是一致的。

真正的系統服務提供者

我們知道Android Framework中系統服務是運行在系統進程中,需要通過Binder機制與應用進程通信,如果我們不考慮系統側實現,上面拿到的類真的應用側的Binder類么?其實并不全是,依舊查看工廠類中的工廠方法:

上面獲取到的服務類,有些類的確是系統側的系統服務對應到應用側的Binder類,比如AlarmManager:

//SystemServiceRegistry.java registerService(Context.ALARM_SERVICE, AlarmManager.class,new CachedServiceFetcher<AlarmManager>() { @Override public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException {IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE);IAlarmManager service = IAlarmManager.Stub.asInterface(b);return new AlarmManager(service, ctx); }}); 有些則是對這些Binder類的直接封裝,比如ActivityManager:

//SystemServiceRegistry.javaregisterService(Context.ACTIVITY_SERVICE, ActivityManager.class,new CachedServiceFetcher<ActivityManager>() { @Override public ActivityManager createService(ContextImpl ctx) {return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }});

其中大量的方法使用getService與getTaskService進行委托:

//ActivityManager.java public void killUid(int uid, String reason) { try { getService().killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } public List<RunningTaskInfo> getRunningTasks(int maxNum) throws SecurityException { try { return getTaskService().getTasks(maxNum); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static IActivityTaskManager getTaskService() { return ActivityTaskManager.getService(); }

而getService與getTaskService都是單例方法,另外使用ServiceManager獲取真正的Binder類。

另外還有些系統服務為了便于使用,封裝得更加復雜,比如WindowManager:

registerService(Context.WINDOW_SERVICE, WindowManager.class,new CachedServiceFetcher<WindowManager>() { @Override public WindowManager createService(ContextImpl ctx) {return new WindowManagerImpl(ctx); }});

這里的各不同Context的WindowManagerImpl會統一調用到WindowManagerGlobal,而WindowManagerGlobal在addView時會創建ViewRootImpl,并將Binder類WindowSession傳遞給ViewRootImpl,由ViewRootImpl完成與WMS通信的工作。

以上實現了獲取系統服務時從應用側到達系統側的過程。

以上就是Android系統服務是如何獲取的的詳細內容,更多關于Android系統服務獲取的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 日鲁夜鲁天天鲁视频 | 国产一级片子 | 国产乱人伦偷精品视频不卡 | 91日韩视频在线观看 | 综合久青草视频 | 午夜精品久久久久久久第一页 | 免费看一级a一片毛片 | 亚洲精品区在线播放一区二区 | 簧片视频在线观看 | 色男人的天堂 | 国产黄色在线看 | 黄色一级短视频 | 亚洲第一页在线观看 | 亚洲欧美日韩成人网 | 亚洲欧美另类精品久久久 | 九一在线完整视频免费观看 | 日韩字幕在线 | 国产精品视频在 | 久久视频6免费观看视频精品 | 精品五夜婷香蕉国产线看观看 | 九九九热精品 | 任我爽在线视频精品凹凸精品分类 | 中国女警察一级毛片视频 | 国产的老妇人 | 亚洲香蕉久久综合网 | 99久久国语对白精品露脸 | 五月亭亭六月丁香 | 美女久久久久久久久久久 | 亚洲欧洲精品视频在线观看 | 后式大肥臀国产在线 | 狠狠色综合久久婷婷 | 国产三级自拍视频 | 亚洲精品丝袜在线一区波多野结衣 | 国产一级做a爰片... | 午夜精品久久久久久 | 亚洲和欧美毛片久久久久 | 久久国产免费福利资源网站 | 国产美女在线一区二区三区 | 97精品国产高清自在线看超 | 成人黄色三级视频 | 日韩欧美久久一区二区 |