<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國際加速解決方案。 廣告
                第二個關鍵點是init函數,該函數將初始化PMS內部的一些重要成員變量,由于此函數代碼較長,此處將分段討論。 從流程角度看,init大體可分為三段。 1. init分析之一 **PowerManagerService.java::init函數** ~~~ void init(Context context, LightsService lights,IActivityManager activity, BatteryService battery) { //①保存幾個成員變量 mLightsService = lights;//保存LightService mContext= context; mActivityService = activity;//保存ActivityManagerService //保存BatteryStatsService mBatteryStats = BatteryStatsService.getService();// mBatteryService = battery;//保存BatteryService //從LightService中獲取代表不同硬件Light的Light對象 mLcdLight= lights.getLight(LightsService.LIGHT_ID_BACKLIGHT); mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS); mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD); mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION); //②調用nativeInit函數 nativeInit(); synchronized (mLocks) { updateNativePowerStateLocked();//③更新Native層的電源狀態 } ~~~ 第一階段工作可分為三步: - 對一些成員變量進行賦值。 - 調用nativeInit函數初始化Native層相關資源。 - 調用updateNativePowerStateLocked更新Native層的電源狀態。這個函數的調用次數較為頻繁,以后續分析時討論。 先來看第一階段出現的各類成員變量,如表5-1所示。 :-: 表5-1 成員變量說明 | 成員變量名 | 數據類型 | 作用 | | --- | --- | --- | | mLightsService | LightsService| 和LightsService交互用 | |mActivityService | IActivityManager | 和ActivityManagerService交互 | | mBatteryStats | IBatteryStats | 和BatteryStatsService交互,用于系統耗電量統計方面的工作 | | mBatteryService | BatteryService | 用于獲取電源狀態,例如是否為低電狀態、查詢電池電量等 | | mLcdLight、mButtonLight、mKeyboardLight、mAttentionLight| LightsService.Light| 由PMS控制,在不同狀態下點亮或熄滅它們 | 下面來看nativeInit函數,其JNI層實現代碼如下: **com_android_server_PowerManagerService.cpp** ~~~ static void android_server_PowerManagerService_nativeInit(JNIEnv*env, jobject obj) { //非常簡單,就是創建一個全局引用對象gPowerManagerServiceObj gPowerManagerServiceObj = env->NewGlobalRef(obj); } ~~~ init第一階段工作比較簡單,下面進入第二階段的分析。 2. init分析之二 init第二階段工作將創建兩個HandlerThread對象,即創建兩個帶消息循環的工作線程。PMS本身由ServerThread線程創建,并且將自己的工作委托給這兩個線程,它們分別是: - mScreenOffThread:按Power鍵關閉屏幕時,屏幕不是突然變黑的,而是一個漸暗的過程。mScreenOffThread線程就用于控制關屏過程中的亮度調節。 - mHandlerThread:該線程是PMS的主要工作線程。 先來看這兩個線程的創建。 (1) mScreenOffThread和mHandlerThread分析 **PowerManagerService.java::init函數** ~~~ ...... mScreenOffThread= new HandlerThread("PowerManagerService.mScreenOffThread") { protected void onLooperPrepared() { mScreenOffHandler = new Handler();//向這個handler發送的消息,將由此線程處理 synchronized (mScreenOffThread) { mInitComplete = true; mScreenOffThread.notifyAll(); } } }; mScreenOffThread.start();//創建對應的工作線程 synchronized (mScreenOffThread) { while(!mInitComplete) { try {//等待mScreenOffThread線程創建完成 mScreenOffThread.wait(); } ...... } } ~~~ * * * * * **注意**,在Android代碼中經常出現“線程A創建線程B,然后線程A等待線程B創建完成”的情況,讀者了解它們的作用即可。接著看以下代碼。 * * * * * **PowerManagerService.java::init函數** ~~~ mInitComplete= false; //創建 mHandlerThread mHandlerThread = new HandlerThread("PowerManagerService") { protectedvoid onLooperPrepared() { super.onLooperPrepared(); initInThread();//①初始化另外一些成員變量 } }; mHandlerThread.start(); ......//等待mHandlerThread創建完成 ~~~ 由于mHandlerThread承擔了PMS的主要工作任務,因此需要先做一些初始化工作,相關的代碼在initInThread中,擬放在單獨一節中進行討論。 (2) initInThread分析 initInThread本身比較簡單,涉及三個方面的工作,總結如下: - PMS需要了解外面的世界,所以它會注冊一些廣播接收對象,接收諸如啟動完畢、電池狀態變化等廣播。 - PMS所從事的電源管理工作需要遵守一定的規則,而這些規則在代碼中就是一些配置參數,這些配置參數的值可以是固定寫死的(編譯完后就無法改動),也可以是經由Settings數據庫動態設定的。 - PMS需要對外發出一些通知,例如屏幕關閉/屏幕開啟。 了解initInThread的概貌后,再來看如下代碼。 **PowerManagerService.java::initInThread** ~~~ void initInThread() { mHandler= new Handler(); //PMS內部也需要使用WakeLock,此處定義了幾種不同的UnsynchronizedWakeLock。它們的 //作用見后文分析 mBroadcastWakeLock = newUnsynchronizedWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true); //創建廣播通知的Intent,用于通知SCREEN_ON和SCREEN_OFF消息 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); //取配置參數,這些參數是編譯時確定的,運行過程中無法修改 Resourcesresources = mContext.getResources(); mAnimateScreenLights = resources.getBoolean( com.android.internal.R.bool.config_animateScreenLights); ......//見下文的配置參數匯總 //通過數據庫設置的配置參數 ContentResolver resolver =mContext.getContentResolver(); Cursor settingsCursor =resolver.query(Settings.System.CONTENT_URI, null, ......//設置查詢條件和查詢項的名字,見后文的配置參數匯總 null); //ContentQueryMap是一個常用類,簡化了數據庫查詢工作。讀者可參考SDK中該類的說明文檔 mSettings= new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler); //監視上邊創建的ContentQueryMap中內容的變化 SettingsObserver settingsObserver = new SettingsObserver(); mSettings.addObserver(settingsObserver); settingsObserver.update(mSettings, null); //注冊接收通知的BroadcastReceiver IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); mContext.registerReceiver(new BatteryReceiver(), filter); filter =new IntentFilter(); filter.addAction(Intent.ACTION_BOOT_COMPLETED); mContext.registerReceiver(new BootCompletedReceiver(), filter); filter =new IntentFilter(); filter.addAction(Intent.ACTION_DOCK_EVENT); mContext.registerReceiver(new DockReceiver(), filter); //監視Settings數據中secure表的變化 mContext.getContentResolver().registerContentObserver( Settings.Secure.CONTENT_URI, true, new ContentObserver(new Handler()) { public void onChange(boolean selfChange) { updateSettingsValues(); } }); updateSettingsValues(); ......//通知其他線程 } ~~~ 在上述代碼中,很大一部分用于獲取配置參數。同時,對于數據庫中的配置值,還需要建立監測機制,細節部分請讀者自己閱讀相關代碼,這里總結一下常用的配置參數,如表5-2所示。 :-: 表5-2 PMS使用的配置參數 | 參數名:類型 | 來源 | 備注 | | --- | --- | --- | | mAnimateScreenLights:bool | config.xml[^write]| 關屏時屏幕光是否漸暗,默認為true | | mUnplugTurnsOnScreen:bool | config.xml | 拔掉USB線,是否點亮屏幕 | | mScreenBrightnessDim:int | config.xml | PMS可設置的屏幕亮度的最小值,默認20(單位lx) | | mUseSoftwareAutoBrightness:bool | config.xml | 是否啟用Setting中的亮度自動調節,如果硬件不支持該功能,則可由軟件控制。默認為false | |mAutoBrightnessLevels:int[]、mLcdBacklightValues:int[] 、…… | config.xml,具體值由硬件廠商定義 | 當使用軟件自動亮度調節時,需配置不同亮度時對應的參數 | | STAY_ON_WHILE_PLUGGED_IN:int | Settings.db | 插入USB時是否保持喚醒狀態 | | SCREEN_OFF_TIMEOUT:int | Settings.db | 屏幕超時時間 | | DIM_SCREEN:int | Settings.db |是否變暗(dim)屏幕 | | SCREEN_BRIGHTNESS_MODE:int | Settings.db |屏幕亮度模式(自動還是手動調節) | 除了獲取配置參數外,initInThread還創建了好幾個UnsynchronizedWakeLock對象,它的作用是:在Android系統中,為了搶占電力資源,客戶端要使用WakeLock對象。PMS自己也不例外,所以為了保證在工作中不至于突然掉電(當其他客戶端都不使用WakeLock的時候,這種情況理論上是有可能發生的),PMS需要定義供自己使用的WakeLock。由于線程同步方面的原因,PMS封裝了一個UnsynchronizedWakeLock結構,它的調用已經處于鎖保護下,所以在內部無需再做同步處理。UnsynchronizedWakeLock比較簡單,因此不再贅述。 下面來看init第三階段的工作。 3. init分析之三 **PowerManagerService.java::init函數** ~~~ nativeInit();//不知道此處為何還要調用一次nativeInit,筆者懷疑此處為bug synchronized (mLocks) { updateNativePowerStateLocked();//更新native層power狀態,以后分析 forceUserActivityLocked();//強制觸發一次用戶事件 mInitialized = true; }//init函數完畢 ~~~ forceUserActivityLocked表示強制觸發一次用戶事件。這個解釋是否會讓讀者丈二和尚摸不著頭?先來看它的代碼: **PowerManagerService.java:: forceUserActivityLocked** ~~~ private void forceUserActivityLocked() { if(isScreenTurningOffLocked()) { mScreenBrightness.animating = false; } boolean savedActivityAllowed =mUserActivityAllowed; mUserActivityAllowed = true; //下面這個函數以后會分析, SDK中有對應的API userActivity(SystemClock.uptimeMillis(), false); mUserActivityAllowed= savedActivityAllowed; } ~~~ forceUserActivityLocked內部就是為調用userActivity掃清一切障礙。對于SDK中PowerManager.userActivity的說明文檔“User activity happened.Turnsthe device from whatever state it's in to full on, and resets the auto-offtimer.”簡單翻譯過來是:調用此函數后,手機將被喚醒。屏幕超時時間將重新計算。 userActivity是PMS中很重要的一個函數,本章后面將對其進行詳細分析。 4. init函數總結 PMS的init函數比較簡單,但是其眾多的成員變量讓人感到有點頭暈。讀者自行閱讀代碼時,不妨參考表5-1和表5-2。 [^write]: config.xml文件的全路徑是4.0源碼/frameworks/base/core/res/res/values/config.xml。
                  <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>

                              哎呀哎呀视频在线观看