<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                AMS的setSystemProcess的代碼如下: **ActivityManagerService.java::setSystemProcess** ~~~ public static void setSystemProcess() { try { ActivityManagerService m = mSelf; //向ServiceManager注冊幾個服務 ServiceManager.addService("activity",m); //用于打印內存信息 ServiceManager.addService("meminfo", new MemBinder(m)); /* Android4.0新增的,用于打印應用進程使用硬件顯示加速方面的信息(Applications Graphics Acceleration Info)。讀者通過adb shell dumpsys gfxinfo看看具體的 輸出 */ ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); if(MONITOR_CPU_USAGE)//該值默認為true,添加cpuinfo服務 ServiceManager.addService("cpuinfo", new CpuBinder(m)); //向SM注冊權限管理服務PermissionController ServiceManager.addService("permission", newPermissionController(m)); /* 重要說明: 向PackageManagerService查詢package名為"android"的ApplicationInfo。 注意這句調用:雖然PKMS和AMS同屬一個進程,但是二者交互仍然借助Context。 其實,此處完全可以直接調用PKMS的函數。為什么要費如此周折呢 */ ApplicationInfo info = //使用AMS的mContext對象 mSelf.mContext.getPackageManager().getApplicationInfo( "android",STOCK_PM_FLAGS); //①調用ActivityThread的installSystemApplicationInfo函數 mSystemThread.installSystemApplicationInfo(info); synchronized (mSelf) { //②此處涉及AMS對進程的管理,見下文分析 ProcessRecord app = mSelf.newProcessRecordLocked( mSystemThread.getApplicationThread(), info, info.processName);//注意,最后一個參數為字符串,值為“system” app.persistent = true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; //③保存該ProcessRecord對象 mSelf.mProcessNames.put(app.processName, app.info.uid, app); synchronized (mSelf.mPidsSelfLocked) { mSelf.mPidsSelfLocked.put(app.pid, app); } //根據系統當前狀態,調整進程的調度優先級和OOM_Adj,后續將詳細分析該函數 mSelf.updateLruProcessLocked(app, true,true); } } ......//拋異常 } ~~~ 在以上代碼中列出了一個重要說明和兩個關鍵點。 - 重要說明:AMS向PKMS查詢名為“android”的ApplicationInfo。此處AMS和PKMS的交互是通過Context來完成的,查看這一系列函數調用的代碼,最終發現AMS將通過Binder發送請求給PKMS來完成查詢功能。AMS和PKMS同屬一個進程,它們完全可以不通過Context來交互。此處為何要如此大費周章呢?原因很簡單,Android希望SystemServer中的服務也通過Android運行環境來交互。這更多是從設計上來考慮的,比如組件之間交互接口的統一及未來系統的可擴展性。 - 關鍵點一:ActivityThread的installSystemApplicationInfo函數。 - 關鍵點二:ProcessRecord類,它和AMS對進程的管理有關。 通過重要說明,相信讀者能真正理解AMS的 main函數中第二個隱含目的的作用,故此處不再展開敘述。 現在來看第一個關鍵點,即ActivityThread的installSystemApplicationInfo函數。 1. ActivityThread的installSystemApplicationInfo函數分析 installSystemApplicationInfo函數的參數為一個ApplicationInfo對象,該對象由AMS通過Context查詢PKMS中一個名為“android”的package得來(根據前面介紹的知識,目前只有framework-res.apk聲明其package名為“android”)。 再來看installSystemApplicationInfo的代碼,如下所示: **ActivityThread.java::installSystemApplicationInfo** ~~~ public voidinstallSystemApplicationInfo(ApplicationInfo info) { synchronized (this) { //返回的ContextImpl對象即之前在AMS的main函數一節中創建的那個對象 ContextImpl context = getSystemContext(); //又調用init初始化該Context,是不是重復調用init了? context.init(new LoadedApk(this, "android", context, info, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this); //創建一個Profiler對象,用于性能統計 mProfiler = new Profiler(); } } ~~~ 在以上代碼中看到調用context.init的地方,讀者可能會有疑惑,getSystemContext函數將返回mSystemContext,而此mSystemContext在AMS的main函數中已經初始化過了,此處為何再次初始化呢? 仔細查看看代碼便會發現: - 第一次執行init時,在LoadedApk構造函數中第四個表示ApplicationInfo的參數為null。 - 第二次執行init時,LoadedApk構造函數的第四個參數不為空,即該參數將真正指向一個實際的ApplicationInfo,該ApplicationInfo來源于framework-res.apk。 基于上面的信息,某些讀者可能馬上能想到:Context第一次執行init的目的僅僅是為了創建一個Android運行環境,而該Context并沒有和實際的ApplicationInfo綁定。而第二次執行init前,先利用Context和PKMS交互得到一個實際的ApplicationInfo,然后再通過init將此Context和ApplicationInfo綁定。 是否覺得前面的疑惑已豁然而解?且慢,此處又拋出了一個更難的問題: 第一次執行init后得到的Context雖然沒有綁定ApplicationInfo,不是也能使用嗎?此處為何非要和一個ApplicationInfo綁定? 答案很簡單,因為framework-res.apk(包括后面將介紹的SettingsProvider.apk)運行在SystemServer中。和其他所有apk一樣,它的運行需要一個正確初始化的Android運行環境。 長噓一口氣,這個大難題終于弄明白了!在此即基礎上,AMS下一步的工作就就順理成章了。 由于framework-res.apk是一個APK文件,和其他APK文件一樣,它應該運行在一個進程中。而AMS是專門用于進程管理和調度的,所以運行APK的進程應該在AMS中有對應的管理結構。因此AMS下一步工作就是將這個運行環境和一個進程管理結構對應起來并交由AMS統一管理。 AMS中的進程管理結構是ProcessRecord。 2. 關于ProcessRecord和IApplicationThread的介紹 分析ProcessRecord之前,先來思考一個問題: AMS如何與應用進程交互?例如AMS啟動一個位于其他進程的Activity,由于該Activity運行在另外一進程中,因此AMS勢必要和該進程進行跨進程通信。 答案自然是通過Binder進行通信。為此,Android提供了一個IApplicationThread接口,該接口定義了AMS和應用進程之間的交互函數,如圖6-5所示為該接口的家族圖譜。 :-: ![](http://img.blog.csdn.net/20150803122712043?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖6-5 ApplicationThread類 由圖6-5可知: - ApplicationThreadNative實現了IApplicationThread接口。從該接口定義的函數可知,AMS通過它可以和應用進程進行交互,例如,AMS啟動一個Activity的時候會調用該接口的scheduleLaunchActivity函數。 - ActivityThread通過成員變量mAppThread指向它的內部類ApplicationThread,而ApplicationThread從ApplicationThreadNative派生。 基于以上知識,讀者能快速得出下面問題的答案嗎?IApplicationThread的Binder服務端在應用進程中還是在AMS中? * * * * * **提示**:如果讀者知道Binder系統支持客戶端監聽服務端的死亡消息,那么這個問題的答案就簡單了:服務端自然在應用進程中,因為AMS需要監聽應用進程的死亡通知。 * * * * * 有了IApplicationThread接口,AMS就可以和應用進程交互了。例如,對于下面一個簡單的函數: **ActivityThread.java::scheduleStopActivity** ~~~ public final void scheduleStopActivity(IBindertoken, boolean showWindow, intconfigChanges) { queueOrSendMessage(//該函數內部將給一個Handler發送對應的消息 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, token, 0, configChanges); } ~~~ 當AMS想要停止(stop)一個Activity時,會調用對應進程IApplicationThread Binder客戶端的scheduleStopActivity函數。該函數服務端實現的就是向ActivityThread所在線程發送一個消息。在應用進程中,ActivityThread運行在主線程中,所以這個消息最終在主線程被處理。 * * * * * **提示**:Activity的onStop函數也將在主線程中被調用。 * * * * * IApplicationThread僅僅是AMS和另外一個進程交互的接口,除此之外,AMS還需要更多的有關該進程的信息。在AMS中,進程的信息都保存在ProcessRecord數據結構中。那么,ProcessRecord是什么呢?先來看setSystemProcess的第二個關鍵點,即newProcessRecordLocked函數,其代碼如下: **ActivityManagerService.java::newProcessRecordLocked** ~~~ final ProcessRecordnewProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess) { Stringproc = customProcess != null ? customProcess : info.processName; BatteryStatsImpl.Uid.Proc ps = null; BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { //BSImpl將為該進程創建一個耗電量統計項 ps =stats.getProcessStatsLocked(info.uid, proc); } //創建一個ProcessRecord對象,用于和其他進程通信的thread作為第一個參數 returnnew ProcessRecord(ps, thread, info, proc); } ~~~ ProcessRecord的成員變量較多,先來看看再其構造函數中都初始化了哪些成員變量。 **ProcessRecord.java::ProcessRecord** ~~~ ProcessRecord(BatteryStatsImpl.Uid.Proc_batteryStats, IApplicationThread_thread,ApplicationInfo _info, String _processName) { batteryStats = _batteryStats; //用于電量統計 info =_info; //保存ApplicationInfo processName = _processName; //保存進程名 //一個進程能運行多個Package,pkgList用于保存package名 pkgList.add(_info.packageName); thread= _thread;//保存IApplicationThread,通過它可以和應用進程交互 //下面這些xxxAdj成員變量和進程調度優先級及OOM_adj有關。以后再分析它的作用 maxAdj= ProcessList.EMPTY_APP_ADJ; hiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; curRawAdj = setRawAdj = -100; curAdj= setAdj = -100; //用于控制該進程是否常駐內存(即使被殺掉,系統也會重啟它),只有重要的進程才會有此待遇 persistent = false; removed= false; } ~~~ ProcessRecord除保存和應用進程通信的IApplicationThread對象外,還保存了進程名、不同狀態對應的Oom_adj值及一個ApplicationInfo。一個進程雖然可運行多個Application,但是ProcessRecord一般保存該進程中先運行的那個Application的ApplicationInfo。 至此,已經創建了一個ProcessRecord對象,和其他應用進程不同的是,該對象對應的進程為SystemServer。為了彰顯其特殊性,AMS為其中的一些成員變量設置了特定的值: ~~~ app.persistent = true;//設置該值為true app.pid =MY_PID;//設置pid為SystemServer的進程號 app.maxAdj= ProcessList.SYSTEM_ADJ;//設置最大OOM_Adj,系統進程默認值為-16 //另外,app的processName被設置成“system” ~~~ 這時,一個針對SystemServer的ProcessRecord對象就創建完成了。此后AMS將把它并入自己的勢力范圍內。 AMS中有兩個成員變量用于保存ProcessRecord,一個是mProcessNames,另一個是mPidsSelfLocked,如圖6-6所示為這兩個成員變量的數據結構示意圖。 :-: ![](http://img.blog.csdn.net/20150803122730451?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖6-6 mPidsSelfLocked和mProcessNames數據結構示意圖 3. AMS的setSystemProcess總結 現在來總結回顧setSystemProcess的工作: - 注冊AMS、meminfo、gfxinfo等服務到ServiceManager中。 - 根據PKMS返回的ApplicationInfo初始化Android運行環境,并創建一個代表SystemServer進程的ProcessRecord,從此,SystemServer進程也并入AMS的管理范圍內。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看