




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Android 7.0 ActivityManagerService(1) AMS的啟動過程一、概況 ActivityManagerService(AMS)是Android中最核心的服務,主要負責系統(tǒng)中四大組件的啟動、切換、調度及應用程序的管理和調度等工作。AMS通信結構如下圖所示:從圖中可以看出: 1、AMS繼承自ActivityManagerNative(AMN),并實現了Watchdog.Monitor和BatteryStatsImpl.BatteryCallback接口。2、AMN繼承Java的Binder類,同時實現了IActivityManager接口,即AMN將作為Binder通
2、信的服務端為用戶提供支持。3、在ActivityManagerNative類中定義了內部類ActivityManagerProxy,該類同樣實現了IActivityManager接口,將作為客戶端使用的服務端代理。4、其它進程將使用ActivityManager來使用AMS的服務。ActivityManager通過AMN提供的getDefault接口得到ActivityManagerProxy,然后再以Binder通信的方式調用AMS的接口。對AMS的基本情況有一個大概的了解后,我們一起來分析一下AMS的啟動過程。 由于AMS啟動涉及的內容比較多,我們將分段進行分析。二、createSyste
3、mContext 在進入到AMS相關的流程前,我們需要先了解一下相關的準備工作。我們已經知道了,zygote創(chuàng)建出的第一個java進程是SystemServer。 在SystemServer的run函數中,在啟動AMS之前,調用了createSystemContext函數。其代碼如下所示:./SystemServer在啟動任何服務之前,就調用了createSystemContext/創(chuàng)建出的Context保存在mSystemContext中/ Initialize the system context.createSystemContext();/ Create the system serv
4、ice manager./SystemServiceManager負責啟動所有的系統(tǒng)服務,使用的Context就是mSystemContextmSystemServiceManager = new SystemServiceManager(mSystemContext);.我們跟進一下createSystemContext:private void createSystemContext() /調用ActivityThread的systemMain函數,其中會創(chuàng)建出系統(tǒng)對應的Context對象 ActivityThread activityThread = ActivityThread.sys
5、temMain(); /取出上面函數創(chuàng)建的Context對象,保存在mSystemContext中 mSystemContext = activityThread.getSystemContext(); /設置系統(tǒng)主題 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);以上函數中,最重要的就是ActivityThread.systemMain了,我們分析一下該函數。1、ActivityThread.systemMainpublic static ActivityThread systemMain() / The system process on lo
6、w-memory devices do not get to use hardware / accelerated drawing, since this can add too much overhead to the / process. if (!ActivityManager.isHighEndGfx() /雖然寫著ActivityManager,但和AMS沒有任何關系 /就是利用系統(tǒng)屬性和配置信息進行判斷 /關閉硬件渲染功能 ThreadedRenderer.disable(true); else ThreadedRenderer.enableForegroundTrimming()
7、; /創(chuàng)建ActivityThread ActivityThread thread = new ActivityThread(); /調用attach函數,參數為true thread.attach(true); return thread;從上面的代碼可以看出,ActivityThread的systemMain函數中,除了進行是否開啟硬件渲染的判斷外,主要作用是: 創(chuàng)建出ActivityThread對象,然后調用該對象的attach函數。ActivityThread的構造函數比較簡單:ActivityThread() mResourcesManager = ResourcesManager.
8、getInstance();比較關鍵的是它的成員變量:./定義了AMS與應用通信的接口final ApplicationThread mAppThread = new ApplicationThread();/擁有自己的looper,說明ActivityThread確實可以代表事件處理線程final Looper mLooper = Looper.myLooper();/H繼承Handler,ActivityThread中大量事件處理依賴此Handlerfinal H mH = new H();/用于保存該進程的ActivityRecordfinal ArrayMap mActivities
9、= new ArrayMap()./用于保存進程中的Servicefinal ArrayMap mServices = new ArrayMap();./用于保存進程中的Applicationfinal ArrayList mAllApplications = new ArrayList();.我們需要知道的是,ActivityThread是Android Framework中一個非常重要的類,它代表一個應用進程的主線程,其職責就是調度及執(zhí)行在該線程中運行的四大組件。 在Android中,應用進程指那些運行APK的進程,它們由zygote fork出來,其中運行著獨立的dalvik虛擬機。 與
10、應用進程相對的就是系統(tǒng)進程,例如zygote和SystemServer。注意到此處的ActivityThread創(chuàng)建于SystemServer進程中。 由于SystemServer中也運行著一些系統(tǒng)APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以認為SystemServer是一個特殊的應用進程。對于上面提到的ActivityThread的成員變量,其用途基本上可以從名稱中得知,這里僅說明一下ApplicationThread。AMS負責管理和調度進程,因此AMS需要通過Binder機制和應用進程通信。 為此,Android提供了一個IApp
11、licationThread接口,該接口定義了AMS和應用進程之間的交互函數。如上圖所示,ActivityThread作為應用進程的主線程代表,在其中持有ApplicationThread。ApplicationThread繼承ApplicationThreadNative。 當AMS與應用進程通信時,ApplicationThread將作為Binder通信的服務端。AMS與應用進程通信時,通過ApplicationThreadNative獲取應用進程對應的ApplicationThreadProxy對象。 通過ApplicationThreadProxy對象,將調用信息通過Binder傳遞到
12、ActivityThread中的ApplicationThread。 這個調用過程,今后還會遇到,碰到的時候再詳細分析。2、ActivityThread.attach 我們看看ActivityThread的attach函數:/此時,我們傳入的參數為true,表示該ActivityThread是系統(tǒng)進程的ActivityThreadprivate void attach(boolean system) /創(chuàng)建出的ActivityThread保存在類的靜態(tài)變量sCurrentActivityThread /AMS中的大量操作將會依賴于這個ActivityThread sCurrentActivit
13、yThread = this; mSystemThread = system; if (!system) /應用進程的處理流程 . else /系統(tǒng)進程的處理流程,該情況只在SystemServer中處理 / Dont set application object here - if the system crashes, / we cant display an alert, we just want to die die die. /設置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer進程的名稱為“system_process” andr
14、oid.ddm.DdmHandleAppName.setAppName(system_process, UserHandle.myUserId(); try /創(chuàng)建ActivityThread中的重要成員:Instrumentation、Application和Context mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = conte
15、xt.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); catch (Exception e) throw new RuntimeException( Unable to instantiate Application(): + e.toString(), e); /以下系統(tǒng)進程和非系統(tǒng)進程均會執(zhí)行 . /注冊Configuration變化的回調通知 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() Override public v
16、oid onConfigurationChanged(Configuration newConfig) /當系統(tǒng)配置發(fā)生變化時(例如系統(tǒng)語言發(fā)生變化),回調該接口 . . );從上面的代碼可以看出,對于系統(tǒng)進程而言,ActivityThread的attach函數最重要的工作就是創(chuàng)建了Instrumentation、Application和Context。2.1 Instrumentation Instrumentation是Android中的一個工具類,當該類被啟用時,它將優(yōu)先于應用中其它的類被初始化。 此時,系統(tǒng)先創(chuàng)建它,再通過它創(chuàng)建其它組件。此外,系統(tǒng)和應用組件之間的交互也將通過Instr
17、umentation來傳遞。 因此,Instrumentation就能監(jiān)控系統(tǒng)和組件的交互情況了。實際使用時,可以創(chuàng)建該類的派生類進行相應的操作。 這個類在介紹啟動Activity的過程時還會碰到,此處不作展開。2.2 Context Context是Android中的一個抽象類,用于維護應用運行環(huán)境的全局信息。 通過Context可以訪問應用的資源和類,甚至進行系統(tǒng)級的操作,例如啟動Activity、發(fā)送廣播等。ActivityThread的attach函數中,通過下面的代碼創(chuàng)建出系統(tǒng)應用對應的Context:./ContextImpl是Context的實現類ContextImpl cont
18、ext = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo);.2.2.1 getSystemContext 我們先看看ActivityThread中getSystemContext的內容:public ContextImpl getSystemContext() synchronized (this) if (mSystemContext = null) /調用ContextImpl的靜態(tài)函數createSystemContext mSystemContext = ContextImpl.createSy
19、stemContext(this); return mSystemContext; 進入ContextImpl的createSystemContext函數:static ContextImpl createSystemContext(ActivityThread mainThread) /創(chuàng)建LoadedApk類,代表一個加載到系統(tǒng)中的APK /注意此時的LoadedApk只是一個空殼 /PKMS還沒有啟動,估無法得到有效的ApplicationInfo LoadedApk packageInfo = new LoadedApk(mainThread); /調用ContextImpl的構造函數
20、 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY); /初始化資源信息 context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics(); return context;可以看出createSystemConte
21、xt的內容就是創(chuàng)建一個LoadedApk,然后初始化一個ContextImpl對象。 似乎沒有什么特別的,那么為什么函數名被叫做create “System” Context?為了回答這個問題,就要看看LoadedApk的構造函數了:LoadedApk(ActivityThread activityThread) mActivityThread = activityThread; mApplicationInfo = new ApplicationInfo(); /packageName為android mApplicationInfo.packageName = android; mPack
22、ageName = android; /下面許多參數為null .注意到createSystemContext函數中,創(chuàng)建的LoadApk對應packageName為”android”,也就是framwork-res.apk。 由于該APK僅供SystemServer進程使用,因此創(chuàng)建的Context被定義為System Context。 現在該LoadedApk還沒有得到framwork-res.apk實際的信息。當PKMS啟動,完成對應的解析后,AMS將重新設置這個LoadedApk。2.2.2 ContextImpl.createAppContextstatic ContextImpl
23、createAppContext(ActivityThread mainThread, LoadedApk packageInfo) if (packageInfo = null) throw new IllegalArgumentException(packageInfo); return new ContextImpl(null, mainThread, packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);相對而言,createAppContext的內容就比較簡單了,就是利用ActivityThread和Load
24、edApk構造出ContextImpl。 ContextImpl的構造函數主要是完成一些變量的初始化,建立起ContextImpl與ActivityThread、LoadedApk、ContentResolver之間的關系。 代碼簡單但是冗長,此處不做展開。2.3 Application Android中Application類用于保存應用的全局狀態(tài)。我們經常使用的Activity和Service均必須和具體的Application綁定在一起。 通過上圖的繼承關系,每個具體的Activity和Service均被加入到Android運行環(huán)境中。在ActivityThread中,針對系統(tǒng)進程,通過
25、下面的代碼創(chuàng)建了初始的Application:./調用LoadedApk的makeApplication函數mInitialApplication = context.mPackageInfo.makeApplication(true, null);/啟動ApplicationmInitialApplication.onCreate();.我們看一下LoadedApk.makeApplication:public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation)
26、if (mApplication != null) return mApplication; . Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass | (appClass = null) /系統(tǒng)進程中,對應下面的appClass appClass = android.app.Application; try java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals(andro
27、id) . ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); /實際上最后通過反射創(chuàng)建出Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); catch (Exception e) . /一個進程支持多個Application,mAllApplications用于保存該進程中的Applicat
28、ion對象 mActivityThread.mAllApplications.add(app); mApplication = app; .從上面的代碼不難看出,這部分主要是創(chuàng)建framework-res.apk對應的Application,然后調用它的onCreate函數,完成啟動??偨Y 至此,createSystemContext函數介紹完畢。當SystemServer調用createSystemContext完畢后: 1、得到了一個ActivityThread對象,它代表當前進程 (此時為系統(tǒng)進程) 的主線程; 2、得到了一個Context對象,對于SystemServer而言,它包含的
29、Application運行環(huán)境與framework-res.apk有關。在繼續(xù)分析AMS之前,我們先停下來思考一下,為什么在啟動所有的服務前,SystemServer先要調用createSystemContext?個人覺得深入理解Android對這個問題,解釋的比較好,大致意思如下: Android努力構筑了一個自己的運行環(huán)境。 在這個環(huán)境中,進程的概念被模糊化了。組件的運行及它們之間的交互均在該環(huán)境中實現。createSystemContext函數就是為SystemServer進程搭建一個和應用進程一樣的Android運行環(huán)境。Android運行環(huán)境是構建在進程之上的,應用程序一般只和And
30、roid運行環(huán)境交互。 基于同樣的道理,SystemServer進程希望它內部運行的應用, 也通過Android運行環(huán)境交互,因此才調用了createSystemContext函數。創(chuàng)建Android運行環(huán)境時, 由于SystemServer的特殊性,調用了ActivityThread.systemMain函數; 對于普通的應用程序,將在自己的主線程中調用ActivityThread.main函數。上圖表示了進程的Android運行環(huán)境涉及的主要類之間的關系。 其中的核心類是ContextImpl,通過它可以得到ContentResolver、系統(tǒng)資源、應用信息等。三、AMS初始化 創(chuàng)建完An
31、droid運行環(huán)境后,SystemServer調用startBootstrapServices,其中就創(chuàng)建并啟動了AMS:private void startBootstrapServices() Installer installer = mSystemServiceManager.startService(Installer.class); / Activity manager runs the show. /啟動AMS,然后獲取AMS保存到變量中 mActivityManagerService = mSystemServiceManager.startService( ActivityM
32、anagerService.Lifecycle.class).getService(); /以下均是將變量存儲到AMS中 mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); .注意到上面的代碼并沒有直接啟動AMS,而是啟動AMS的內部類Lifecycle。 這是迫不得已的做法,由于AMS并沒有繼承SystemService,因此不能通過SystemServiceManager的startService直接啟
33、動它。 可以這樣理解:內部類Lifecycle對于AMS而言,就像一個適配器一樣,讓AMS能夠像SystemService一樣被SystemServiceManager通過反射的方式啟動。public static final class Lifecycle extends SystemService private final ActivityManagerService mService; public Lifecycle(Context context) /Lifecycle由SystemServiceManager啟動,傳入的context就是SystemServer創(chuàng)建出的Syste
34、mContext super(context); /1、調用AMS的構造函數 mService = new ActivityManagerService(context); Override public void onStart() /2、調用AMS的start函數 mService.start(); public ActivityManagerService getService() return mService; 接下來我們分別看看AMS的構造函數和start函數。1、AMS的構造函數 先來看看AMS的構造函數:public ActivityManagerService(Context
35、 systemContext) /AMS的運行上下文與SystemServer一致 mContext = systemContext; . /取出的是ActivityThread的靜態(tài)變量sCurrentActivityThread /這意味著mSystemThread與SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); . mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_
36、FOREGROUND, false /*allowIo*/); mHandlerThread.start(); /處理AMS中消息的主力 mHandler = new MainHandler(mHandlerThread.getLooper(); /UiHandler對應于Android中的UiThread mUiHandler = new UiHandler(); if (sKillHandler = null) sKillThread = new ServiceThread(TAG + :kill, android.os.Process.THREAD_PRIORITY_BACKGROUND
37、, true /* allowIo */); sKillThread.start(); /用于接收消息,殺死進程 sKillHandler = new KillHandler(sKillThread.getLooper(); /創(chuàng)建兩個BroadcastQueue,前臺的超時時間為10s,后臺的超時時間為60s mFgBroadcastQueue = new BroadcastQueue(this, mHandler, foreground, BROADCAST_FG_TIMEOUT, false); mBgBroadcastQueue = new BroadcastQueue(this, m
38、Handler, background, BROADCAST_BG_TIMEOUT, true); mBroadcastQueues0 = mFgBroadcastQueue; mBroadcastQueues1 = mBgBroadcastQueue; /創(chuàng)建變量,用于存儲信息 mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mAppErrors = new AppErrors(mContext, this); /這一部分,分析BatteryStatsService時提過,進行BSS的初始
39、化 File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, system); systemDir.mkdirs(); mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBU
40、G_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); /創(chuàng)建ProcessStatsService,感覺用于記錄進程運行時的統(tǒng)計信息,例如內存使用情況,寫入/proc/stat文件 mProcessStats = new ProcessStatsService(this, new File(systemDir, procstats); /啟動Android的權限檢查服務,
41、并注冊對應的回調接口 mAppOpsService = new AppOpsService(new File(systemDir, appops.xml), mHandler); mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, new IAppOpsCallback.Stub() Override public void opChanged(int op, int uid, String packageName) if (op = AppOpsManager.OP_RUN_IN_BACKGRO
42、UND & packageName != null) if (mAppOpsService.checkOperation(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) runInBackgroundDisabled(uid); ); /用于定義ContentProvider訪問指定Uri對應數據的權限,aosp中似乎沒有這文件 mGrantFile = new AtomicFile(new File(systemDir, urigrants.xml); /創(chuàng)建多用戶管理器 mUserController = new UserContr
43、oller(this); /獲取OpenGL版本 GL_ES_VERSION = SystemProperties.getInt(ro.opengles.version, ConfigurationInfo.GL_ES_VERSION_UNDEFINED); . /資源配置信息置為默認值 mConfiguration.setToDefaults(); mConfiguration.setLocales(LocaleList.getDefault(); mConfigurationSeq = mConfiguration.seq = 1; /感覺用于記錄進程的CPU使用情況 mProcessCp
44、uTracker.init(); /解析/data/system/packages-compat.xml文件,該文件用于存儲那些需要考慮屏幕尺寸的APK的一些信息 /當APK所運行的設備不滿足要求時,AMS會根據xml設置的參數以采用屏幕兼容的方式運行該APK mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); /用于根據規(guī)則過濾一些Intent mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
45、 /以下的類,似乎用于管理和監(jiān)控AMS維護的Activity Task信息 /ActivityStackSupervisor是AMS中用來管理Activity啟動和調度的核心類 mStackSupervisor = new ActivityStackSupervisor(this); mActivityStarter = new ActivityStarter(this, mStackSupervisor); mRecentTasks = new RecentTasks(this, mStackSupervisor); /創(chuàng)建線程用于統(tǒng)計進程的CPU使用情況 mProcessCpuThread
46、 = new Thread(CpuTracker) Override public void run() while (true) try try /計算更新信息的等待間隔 /同時利用wait等待計算出的間隔時間 . catch(InterruptedException e) /更新CPU運行統(tǒng)計信息 updateCpuStatsNow(); catch (Exception e) . ; /加入Watchdog的監(jiān)控 Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler);從代碼來
47、看,AMS的構造函數還是相對比較簡單的,主要工作就是初始化一些變量。 大多數變量的用途,從命名上基本可以推測出來,實際的使用情況必須結合具體的場景才能進一步了解。2、AMS的start函數private void start() /完成統(tǒng)計前的復位工作 Process.removeAllProcessGroups(); /開始監(jiān)控進程的CPU使用情況 mProcessCpuThread.start(); /注冊服務 mBatteryStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d(AppOps, A
48、ppOpsService published); LocalServices.addService(ActivityManagerInternal.class, new LocalService();AMS的start函數比較簡單,主要是: 1、啟動CPU監(jiān)控線程。該線程將會開始統(tǒng)計不同進程使用CPU的情況。 2、發(fā)布一些服務,如BatteryStatsService、AppOpsService(權限管理相關)和本地實現的繼承ActivityManagerInternal的服務。至此AMS初始化相關的內容基本結束,從這些代碼可以看出AMS涉及的類比較多,我們目前無法一一詳述每個類的具體用途。 有機會遇到具體的場景時,再深入分析,此處有個大致印象即可。四、將SystemServer納入AMS的管理體系 1、setSystemProcessAMS完成啟動后,在SystemServer的startBootstrapServices函數中, 下一個與AMS相關的重要調用就是AMS.setSyste
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025春季【高二】【蛇啟新航 蛻變前行】開學第一課-文字稿
- 2025年合同會審單模板
- 二年級上冊數學教案-第五單元第6課時回家路上 北師大版
- 五年級上冊數學教案-2.1 《平行四邊形的面積》 ︳西師大版
- 五年級下冊數學教案 - 露在外面的面 北師大版
- 《長方體和正方體的體積》(教案)青島版五年級下冊數學
- 第6課 貓抓老鼠(教學設計)2023-2024學年五年級上冊信息技術粵教版B版
- 部編版九年級上冊古詩欣賞中考試題匯編(截至2023年)
- 《茅屋為秋風所破歌》歷年中考古詩欣賞試題匯編(截至2024年)
- 2025年河南省鶴壁市單招職業(yè)傾向性測試題庫完整
- 技術規(guī)范書柴油發(fā)電機組
- 青島科技大學成人大?!豆ど唐髽I(yè)管理實訓報告》
- 低鉀血癥最新版本最新課件
- 獸醫(yī)外科手術學與獸醫(yī)外科學章節(jié)測試及答案
- 2023年陜西延長石油礦業(yè)有限責任公司招聘筆試題庫及答案解析
- YY/T 1792-2021熒光免疫層析分析儀
- GB/T 39235-2020豬營養(yǎng)需要量
- GB/T 30799-2014食品用洗滌劑試驗方法重金屬的測定
- 染廠公司簡介(4個范本)
- PPT用中國地圖(可編輯)
- 基于德育的農村中小學校園欺凌現象的解決對策優(yōu)秀獲獎科研論文
評論
0/150
提交評論