日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Android系統(tǒng)服務是如何獲取的

瀏覽:55日期:2022-09-20 11:10:31
關(guān)于獲取系統(tǒng)服務的猜想

Android獲取系統(tǒng)服務一般都需要用getSystemService指定系統(tǒng)服務名稱獲取:

val wm = getSystemService(Context.WINDOW_SERVICE) as WindowManager

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

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

獲取系統(tǒng)服務源碼實現(xiàn)

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

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

SystemServiceRegistry一看就是統(tǒng)一注冊系統(tǒng)服務的地方:

//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; }

這里我們確實發(fā)現(xiàn)了Map,可卻不是從String到系統(tǒng)服務的Map,SYSTEM_SERVICE_FETCHERS的類型為Map<String, ServiceFetcher<?>>。

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

這個SystemServiceRegistry中的內(nèi)部接口ServiceFetcher,看上去像是各種系統(tǒng)服務的工廠接口。我們看它的實現(xiàn)類:

//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[]的數(shù)組ctx.mServiceCache,getService從中用下標mCacheIndex獲取系統(tǒng)服務,如果服務為空則使用createService方法創(chuàng)建服務并放在數(shù)組中。可以說,這個ctx.mServiceCache數(shù)組起到了我們最初設想的從String到系統(tǒng)服務的Map的存放所有系統(tǒng)服務的作用。這個映射變?yōu)榱耍?/p>

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

這個SYSTEM_SERVICE_FETCHERS映射在SystemServiceRegistry的靜態(tài)初始化快中被統(tǒng)一填充,同時提供了上方?jīng)]有實現(xiàn)的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系統(tǒng)服務數(shù)組還是空的,當某一系統(tǒng)服務需要時,上方CachedServiceFetcher中g(shù)etService會調(diào)用createService創(chuàng)建服務并存放在特定mCacheIndex下標中。

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

真正的系統(tǒng)服務提供者

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

上面獲取到的服務類,有些類的確是系統(tǒng)側(cè)的系統(tǒng)服務對應到應用側(cè)的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類。

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

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

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

以上實現(xiàn)了獲取系統(tǒng)服務時從應用側(cè)到達系統(tǒng)側(cè)的過程。

以上就是Android系統(tǒng)服務是如何獲取的的詳細內(nèi)容,更多關(guān)于Android系統(tǒng)服務獲取的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Android
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩一区精品| 欧美.日韩.国产.一区.二区 | 成人精品中文字幕| 欧美日韩视频免费看| 亚洲高清av| 国产一区二区三区久久| 国产伦精品一区二区三区视频| 91久久久精品国产| 99久久www免费| 欧美中文一区二区| 美女国产精品| 久久国产免费看| 国产欧美一区二区三区精品观看| 日韩精品一级二级| 日韩国产欧美在线视频| 国产剧情一区| 国产日韩欧美一区在线| 色婷婷综合网| 国产在线不卡| 日产欧产美韩系列久久99| 蜜桃一区二区三区在线| 蜜臀久久99精品久久久久久9| 亚洲永久字幕| 日韩国产欧美在线播放| 老鸭窝一区二区久久精品| 久久久久99| 午夜日韩在线| 欧美日韩1区2区3区| 国产精东传媒成人av电影| 神马午夜在线视频| 宅男噜噜噜66国产日韩在线观看| 欧美精品一区二区久久| 一区二区国产在线观看| 日本午夜精品久久久| 波多野结衣久久精品| 亚洲香蕉视频| 福利欧美精品在线| 亚洲电影在线| 日韩精品1区2区3区| 国产精品99久久精品| 婷婷色综合网| 国产一区二区三区四区五区传媒| 日韩欧美另类一区二区| 欧美啪啪一区| 黄色在线一区| 国产高潮在线| 亚洲激情久久| 欧美一区成人| 亚洲精品极品少妇16p| 久久99久久人婷婷精品综合| 欧美网站在线| 91视频精品| 国产精品极品在线观看| 视频一区中文字幕| 亚洲性色av| 久久久91麻豆精品国产一区| 亚洲精品影院在线观看| 午夜av一区| 免费在线小视频| 日韩福利一区| 捆绑调教美女网站视频一区| 红桃视频国产一区| 91亚洲国产| 精品视频一区二区三区在线观看| 在线亚洲免费| 亚洲专区视频| 日本午夜精品久久久久| 久久亚洲视频| 三级欧美在线一区| 免费污视频在线一区| 国产精品v一区二区三区| 美日韩精品视频| 亚洲精品97| 日本 国产 欧美色综合| 亚洲精品日本| 精品视频在线你懂得| 国产精品日本一区二区不卡视频| 久久激情综合网| 免费精品视频最新在线| 亚洲人成网站在线在线观看| 亚洲精品乱码| 久久这里只有| 成人精品天堂一区二区三区| 国产v综合v| 伊人久久成人| 日韩精品一区二区三区免费观看| 91精品国产成人观看| 精品国产不卡一区二区| 福利欧美精品在线| 国产v综合v| 欧美在线影院| 国产视频一区在线观看一区免费| 久久网站免费观看| 99精品电影| 国产精品密蕾丝视频下载| 欧美激情福利| 久久久久久美女精品| 国产精品婷婷| 黄色亚洲精品| 欧美国产视频| 亚洲va久久久噜噜噜久久| 亚洲麻豆一区| 婷婷综合五月| 在线精品小视频| 午夜国产精品视频免费体验区| 成人片免费看| 欧美激情另类| 久久亚洲图片| 97成人超碰| 久久精品国产福利| 成人日韩精品| 欧美日韩国产免费观看| 你懂的国产精品永久在线| 国产亚洲在线观看| 精品福利久久久| 91一区二区| 亚洲tv在线| 麻豆一区二区三| 日韩午夜黄色| 精品久久在线| 免费在线成人网| 日韩免费av| 蜜桃av一区二区三区电影| 麻豆91小视频| 国产精品一区二区av日韩在线 | 91久久在线| 国产精品一线| 精品国产不卡| 久久一区精品| 亚洲精品福利| 美女精品在线观看| 精品丝袜在线| 国产一区亚洲| 欧美~级网站不卡| 久久国产精品免费一区二区三区| 国产一区一一区高清不卡| 欧美另类中文字幕 | 日本久久精品| 久久久久91| 亚洲综合激情在线| 国产精品一区二区三区美女| 国产精品日韩精品中文字幕| 免费视频亚洲| 日本三级亚洲精品| 日韩激情一区| 免费日本视频一区| 欧美国产极品| 亚洲香蕉网站| 国产视频一区二区在线播放| 天使萌一区二区三区免费观看| 三级欧美在线一区| 黄毛片在线观看| 亚洲丝袜美腿一区| 国产一区二区高清| 快播电影网址老女人久久| 久久精品 人人爱| 亚洲一区不卡| 免费看日韩精品| 黄色亚洲精品| 久久精品不卡| 国产欧美一区二区精品久久久| 美国欧美日韩国产在线播放| 国产66精品| 欧美在线网站| 黄色成人在线网址| 亚洲精品精选| 福利一区在线| 伊人精品久久| 九九在线精品| 国产日韩一区| 亚洲a一区二区三区| 成人精品国产亚洲| 亚洲欧美日韩精品一区二区| 久久国产日韩| 国产精品亚洲人成在99www| 久久婷婷av| 国产欧美日韩在线一区二区| 国产三级精品三级在线观看国产| 午夜免费一区| 红桃视频国产精品| 久久影视一区| 91成人精品视频| 国产欧美日韩精品一区二区三区| 日本aⅴ亚洲精品中文乱码| 国产精品欧美三级在线观看| 国产精品大片| 红杏一区二区三区| 亚洲午夜天堂| 四虎4545www国产精品 | 日韩专区欧美专区| 蜜桃一区二区三区在线观看| 97精品久久| 日韩一区精品| 久久中文字幕一区二区三区| 婷婷激情久久| 久久精品国产网站| 欧美影院视频| av资源中文在线天堂| 国产午夜精品一区在线观看| 久久中文字幕一区二区三区|