<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                作為核心服務,AMS的systemReady會做什么呢?由于該函數內容較多,我們將它分為三段。首先看第一段的工作。 1. systemReady第一階段的工作 **ActivityManagerService.java::systemReady** ~~~ public void systemReady(final RunnablegoingCallback) { synchronized(this){ ...... if(!mDidUpdate) {//判斷是否為升級 if(mWaitingUpdate) return; //升級未完成,直接返回 //準備PRE_BOOT_COMPLETED廣播 Intent intent = newIntent(Intent.ACTION_PRE_BOOT_COMPLETED); List<ResolveInfo> ris = null; //向PKMS查詢該廣播的接收者 ris= AppGlobals.getPackageManager().queryIntentReceivers( intent, null,0); ......//從返回的結果中刪除那些非系統APK的廣播接收者 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); //讀取/data/system/called_pre_boots.dat文件,這里存儲了上次啟動時候已經 //接收并處理PRE_BOOT_COMPLETED廣播的組件。鑒于該廣播的特殊性,系統希望 //該廣播僅被這些接收者處理一次 ArrayList<ComponentName>lastDoneReceivers = readLastDonePreBootReceivers(); final ArrayList<ComponentName> doneReceivers= newArrayList<ComponentName>(); ......//從PKMS返回的接收者中刪除那些已經處理過該廣播的對象 for (int i=0; i<ris.size(); i++) { ActivityInfo ai = ris.get(i).activityInfo; ComponentName comp = newComponentName(ai.packageName, ai.name); doneReceivers.add(comp); intent.setComponent(comp); IIntentReceiver finisher = null; if (i == ris.size()-1) { //為最后一個廣播接收者注冊一個回調通知,當該接收者處理完廣播后,將調用該 //回調 finisher = new IIntentReceiver.Stub() { public voidperformReceive(Intent intent, int resultCode, Stringdata, Bundle extras, boolean ordered, booleansticky) { mHandler.post(newRunnable() { public void run(){ synchronized(ActivityManagerService.this) { mDidUpdate = true; } //保存那些處理過該廣播的接收者信息 writeLastDonePreBootReceivers(doneReceivers); showBootMessage(mContext.getText( R.string.android_upgrading_complete), false); systemReady(goingCallback); }//run結束 });// new Runnable結束 }//performReceive結束 };//finisher創建結束 }// if (i == ris.size()-1)判斷結束 //發送廣播給指定的接收者 broadcastIntentLocked(null, null, intent,null, finisher, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); if (finisher != null) mWaitingUpdate = true; } if(mWaitingUpdate) return; mDidUpdate= true; } mSystemReady = true; if(!mStartRunning) return; }//synchronized(this)結束 ~~~ 由以上代碼可知,systemReady第一階段的工作并不輕松,其主要職責是發送并處理與PRE_BOOT_COMPLETED廣播相關的事情。目前代碼中還沒有接收該廣播的地方,不過從代碼中的注釋中可猜測到,該廣播接收者的工作似乎和系統升級有關。 建議如有哪位讀者了解與此相關的知識,不妨和大家分享。 下面來介紹systemReady第二階段的工作。 2. systemReady第二階段的工作 **ActivityManagerService.java::systemReady** ~~~ ArrayList<ProcessRecord>procsToKill = null; synchronized(mPidsSelfLocked) { for(int i=mPidsSelfLocked.size()-1; i>=0; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); //從mPidsSelfLocked中找到那些先于AMS啟動的進程,哪些進程有如此能耐, //在AMS還未啟動完畢就啟動完了呢?對,那些聲明了persistent為true的進程有可能 if(!isAllowedWhileBooting(proc.info)){ if (procsToKill == null) procsToKill = new ArrayList<ProcessRecord>(); procsToKill.add(proc); } }//for結束 }// synchronized結束 synchronized(this){ if(procsToKill != null) { for (int i=procsToKill.size()-1; i>=0; i--) { ProcessRecord proc = procsToKill.get(i); //把這些進程關閉,removeProcessLocked函數比較復雜,以后再分析 removeProcessLocked(proc, true, false); } } //至此,系統已經準備完畢 mProcessesReady = true; } synchronized(this) { if(mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { }//和工廠測試有關,不對此進行討論 } //查詢Settings數據,獲取一些配置參數 retrieveSettings(); ~~~ systemReady第二階段的工作包括: - 殺死那些竟然在AMS還未啟動完畢就先啟動的應用進程。注意,這些應用進程一定是APK所在的Java進程,因為只有應用進程才會向AMS注冊,而一般Native(例如mediaserver)進程是不會向AMS注冊的。 - 從Settings數據庫中獲取配置信息,目前只取4個配置參數,分別是:"debug_app"(設置需要debug的app的名稱)、"wait_for_debugger"(如果為1,則等待調試器,否則正常啟動debug_app)、"always_finish_activities"(當一個activity不再有地方使用時,是否立即對它執行destroy)、"font_scale"(用于控制字體放大倍數,這是Android 4.0新增的功能)。以上配置項由Settings數據庫的System表提供。 3. systemReady第三階段的工作 **ActivityManagerService.java::systemReady** ~~~ //調用systemReady傳入的參數,它是一個Runnable對象,下節將分析此函數 if (goingCallback != null) goingCallback.run(); synchronized (this) { if(mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { try{ //從PKMS中查詢那些persistent為1的ApplicationInfo List apps = AppGlobals.getPackageManager(). getPersistentApplications(STOCK_PM_FLAGS); if (apps != null) { int N = apps.size(); int i; for (i=0; i<N; i++) { ApplicationInfo info = (ApplicationInfo)apps.get(i); //由于framework-res.apk已經由系統啟動,所以這里需要把它去除 //framework-res.apk的packageName為"android" if (info != null && !info.packageName.equals("android")) addAppLocked(info);//啟動該Application所在的進程 } } }...... } mBooting= true; //設置mBooting變量為true,其作用后面會介紹 try { if(AppGlobals.getPackageManager().hasSystemUidErrors()) { ......//處理那些Uid有錯誤的Application }...... //啟動全系統第一個Activity,即Home mMainStack.resumeTopActivityLocked(null); }// synchronized結束 } ~~~ systemReady第三階段的工作有3項: - 調用systemReady設置的回調對象goingCallback的run函數。 - 啟動那些聲明了persistent的APK。 - 啟動桌面。 先看回調對象goingCallback的run函數的工作。 (1) goingCallback的run函數分析 **SystemServer.java::ServerThread.run** ~~~ ActivityManagerService.self().systemReady(newRunnable() { publicvoid run() { startSystemUi(contextF);//啟動SystemUi //調用其他服務的systemReady函數 if(batteryF != null) batteryF.systemReady(); if(networkManagementF != null) networkManagementF.systemReady(); ...... Watchdog.getInstance().start();//啟動Watchdog ......//調用其他服務的systemReady函數 } ~~~ run函數比較簡單,執行的工作如下: - 執行startSystemUi,在該函數內部啟動SystemUIService,該Service和狀態欄有關。 - 調用一些服務的systemReady函數。 - 啟動Watchdog。 startSystemUi的代碼如下: `SystemServer.java::startSystemUi` ~~~ static final void startSystemUi(Context context) { Intentintent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); context.startService(intent); } ~~~ SystemUIService由SystemUi.apk提供,它實現了系統的狀態欄。 * * * * * **注意**:在精簡ROM時,也不能刪除SystemUi.apk。 * * * * * (2) 啟動Home界面 如前所述,resumeTopActivityLocked將啟動Home界面,此函數非常重要也比較復雜,故以后再詳細分析。我們提取了resumeTopActivityLocked啟動Home界面時的相關代碼,如下所示: **ActivityStack.java::resumeTopActivityLocked** ~~~ final booleanresumeTopActivityLocked(ActivityRecord prev) { //找到下一個要啟動的Activity ActivityRecord next = topRunningActivityLocked(null); finalboolean userLeaving = mUserLeaving; mUserLeaving = false; if (next== null) { //如果下一個要啟動的ActivityRecord為空,則啟動Home if(mMainStack) {//全系統就一個ActivityStack,所以mMainStack永遠為true //mService指向AMS return mService.startHomeActivityLocked();//mService指向AMS } } ......//以后再詳細分析 } ~~~ 下面來看AMS的startHomeActivityLocked函數,代碼如下: **ActivityManagerService.java::startHomeActivityLocked** ~~~ boolean startHomeActivityLocked() { Intentintent = new Intent( mTopAction, mTopData != null ? Uri.parse(mTopData) :null); intent.setComponent(mTopComponent); if(mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) intent.addCategory(Intent.CATEGORY_HOME);//添加Category為HOME類別 //向PKMS查詢滿足條件的ActivityInfo ActivityInfo aInfo = intent.resolveActivityInfo(mContext.getPackageManager(), STOCK_PM_FLAGS); if(aInfo != null) { intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName,aInfo.name)); ProcessRecordapp = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid); //在正常情況下,app應該為null,因為剛開機,Home進程肯定還沒啟動 if(app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags()| Intent.FLAG_ACTIVITY_NEW_TASK); //啟動Home mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo, null, null, 0, 0, 0, false, false,null); } }//if(aInfo != null)判斷結束 return true; } ~~~ 至此,AMS攜諸位Service都啟動完畢,Home也靚麗登場,整個系統就準備完畢,只等待用戶的檢驗了。不過在分析邏輯上還有一點沒涉及,那會是什么呢? (3) 發送ACTION_BOOT_COMPLETED廣播 由前面的代碼可知,AMS發送了ACTION_PRE_BOOT_COMPLETED廣播,可系統中沒有地方處理它。在前面的章節中,還碰到一個ACTION_BOOT_COMPLETED廣播,該廣播廣受歡迎,卻不知道它是在哪里發送的。 當Home Activity啟動后,ActivityStack的activityIdleInternal函數將被調用,其中有一句代碼頗值得注意: **ActivityStack.java::activityIdleInternal** ~~~ final ActivityRecord activityIdleInternal(IBindertoken, boolean fromTimeout, Configuration config) { booleanbooting = false; ...... if(mMainStack) { booting = mService.mBooting; //在systemReady的第三階段工作中設置該值為true mService.mBooting = false; } ...... if(booting) mService.finishBooting();//調用AMS的finishBooting函數 } ~~~ **ActivityManagerService.java::finishBooting** ~~~ final void finishBooting() { IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); pkgFilter.addDataScheme("package"); mContext.registerReceiver(new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { ......//處理Package重啟的廣播 } }, pkgFilter); synchronized (this) { finalint NP = mProcessesOnHold.size(); if (NP> 0) { ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mProcessesOnHold); for(int ip=0; ip<NP; ip++)//啟動那些等待啟動的進程 startProcessLocked(procs.get(ip), "on-hold", null); } if(mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { //每15鐘檢查系統各應用進程使用電量的情況,如果某進程使用WakeLock時間 //過長,AMS將關閉該進程 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); //設置系統屬性sys.boot_completed的值為1 SystemProperties.set("sys.boot_completed","1"); //發送ACTION_BOOT_COMPLETED廣播 broadcastIntentLocked(null, null, newIntent(Intent.ACTION_BOOT_COMPLETED, null), null, null, 0, null,null, android.Manifest.permission.RECEIVE_BOOT_COMPLETED, false, false, MY_PID,Process.SYSTEM_UID); } } } ~~~ 原來,在Home啟動成功后,AMS才發送ACTION_BOOT_COMPLETED廣播。 4. ASM的 systemReady總結 systemReady函數完成了系統就緒的必要工作,然后它將啟動Home Activity。至此,Android系統就全部啟動了。
                  <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>

                              哎呀哎呀视频在线观看