Android KK开机按power键不能灭屏,须过会儿才能灭屏
这是Google issue,原生Android4.4都有此问题。流程是:AMS发出BOOT_COMPLETED,PowerManager收到BOOT_COMPLETED后check Boot animation是否完成,如果完成,就会将内部的成员mBootCompleted置为true,之后再按power键才会正常休眠。
PowerManagerService.java在systemReady()方法中动态注册BootCompletedReceiver监听ACTION_BOOT_COMPLETED
1 filter = new IntentFilter(); 2 filter.addAction(Intent.ACTION_BOOT_COMPLETED); 3 mContext.registerReceiver(new BootCompletedReceiver(), filter, null, mHandler);
1 private final class BootCompletedReceiver extends BroadcastReceiver { 2 @Override 3 public void onReceive(Context context, Intent intent) { 4 if (DEBUG_SPEW) { 5 Slog.d(TAG, "BootCompletedReceiver."); 6 } 7 // This is our early signal that the system thinks it has finished booting. 8 // However, the boot animation may still be running for a few more seconds 9 // since it is ultimately in charge of when it terminates. 10 // Defer transitioning into the boot completed state until the animation exits. 11 // We do this so that the screen does not start to dim prematurely before 12 // the user has actually had a chance to interact with the device. 13 startWatchingForBootAnimationFinished(); 14 } 15 }
startWatchingForBootAnimationFinished()发送广播MSG_CHECK_IF_BOOT_ANIMATION_FINISHED检查是否开机动画完成,
1 @Override 2 public void handleMessage(Message msg) { 3 switch (msg.what) { 4 …… 5 case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED: 6 checkIfBootAnimationFinished(); 7 break; 8 } 9 }
1 private void checkIfBootAnimationFinished() { 2 if (DEBUG) { 3 Slog.d(TAG, "Check if boot animation finished..."); 4 } 5 // 检查是否还在跑 bootanim 6 if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) { 7 mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED, 8 BOOT_ANIMATION_POLL_INTERVAL); 9 return; 10 } 11 12 synchronized (mLock) { 13 if (!mBootCompleted) { 14 Slog.i(TAG, "Boot animation finished."); 15 handleBootCompletedLocked(); 16 } 17 } 18 }
这里用到SystemService.isRunning(BOOT_ANIMATION_SERVICE)判断系统开机动画是否还在运行,若isRunning继续Check,否则,动画完成handleBootCompletedLocked();
1 private void handleBootCompletedLocked() { 2 final long now = SystemClock.uptimeMillis(); 3 mBootCompleted = true; 4 mDirty |= DIRTY_BOOT_COMPLETED; 5 userActivityNoUpdateLocked( 6 now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); 7 if ( mWakefulness == WAKEFULNESS_AWAKE ) { 8 mNotifier.onWakeUpStarted(); 9 } 10 updatePowerStateLocked(); 11 }
到这里mBootCompleted系统才真正起来,通知更新State。
至此,还是只找到原因,没有好的处理方法,希望高手指点,科普,交流。
目前,比较拙劣的方法是将mBootCompleted=True,设为TRUE。这个改法是让powermanager不去check boot_completed,这样可能会产生影响:刚刚开机就按power键灭屏后,再次按power键是否能正常resume回来。主要是考虑到AMS此时可能还在发BOOT_COMPLETED,而按power键灭屏和亮屏的流程会需要AMS发SCREEN_OFF、SCREEN_ON的intent,担心ActivityManagerService在BOOT_COMPLETED还没发完的情况下又要响应去发SCREEN_OFF和SCREEN_ON。