在长按power键时系统会弹出对话框,让用户选择关机, 重启或者其他模式. 在本文中重点讲解系统关机流程. 让大家了解在系统关机过程都做了哪些事情,而导致关机慢又有那些主要的原因.在Android7.0 PowerManagerService亮灭屏(一)一文中有对按power键传输讲解, 长按power键是在java层的PhoneWindowManager.java中进行处理的.
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
//..........
// When interactive, we're already awake.
// Wait for a long press or for the button to be released to decide what to do.
if (hasLongPressOnPowerBehavior()) { //是否存在长按事件
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true); //如果是长按power键就发送MSG_POWER_LONG_PRESS
mHandler.sendMessageDelayed(msg, //发送delay消息, delay 500ms给用户一些时间长按power键显示关机dialog, 同时delay时间也可以通过config.xml中配置
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
//........
}
延迟消息最终会在PolicyHandler的handleMessage中处理长按事件.
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
//......
case MSG_POWER_LONG_PRESS:
powerLongPress(); //处理长按事件
break;
//........
}
}
}
当长按power键时可能会有不同的behavior,可能什么都不做, 也可能直接关机,没有给用户任何提醒. 或者弹出dialog让用户自己选择. 下面将主要讲解弹出dialog关机的情况.
static final int LONG_PRESS_POWER_NOTHING = 0; //长按power键什么都不做
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; //为全局动作, 显示关机dialog
static final int LONG_PRESS_POWER_SHUT_OFF = 2; //只有关机一个选项
static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3; //直接关机不用确认
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior(); //获取长按power键要做的事情
switch (behavior) {
case LONG_PRESS_POWER_NOTHING: //返回,什么都不做
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
showGlobalActionsInternal(); //显示全局的dialog
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM: //直接关机
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
}
}
在显示关机dialog时需要将其他的系统dialogs都关闭了, 优先处理关机dialog, 之后就创建mGlobalActions显示dialog.\
void showGlobal