标签:style java for ar art 问题 cti 代码 log
文章仅记录自己的一点理解,仅供自己参考。
1、mInputFocus
WMS.addWindow()-->WMS.finishUpdateFocusedWindowAfterAssignLayersLocked()-->InputMonitor.setInputFocusLw()-->mInputFocus = newWindow;
add一个window的时候会重新寻找焦点窗口,并把焦点窗口保存在WMS.mCurrentFocus中,这个焦点窗口也会保存到InputMonitor.mInputFocus 中。关键代码:
<span style="font-size:18px;">addWindow(){ …… boolean focusChanged = false; if (win.canReceiveKeys()) { focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, false /*updateInputWindows*/); if (focusChanged) { imMayMove = false; } } if (imMayMove) { moveInputMethodWindowsIfNeededLocked(false); } assignLayersLocked(displayContent.getWindowList()); // Don't do layout here, the window must call // relayout to be displayed, so we'll do it there. if (focusChanged) { finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/); } mInputMonitor.updateInputWindowsLw(false /*force*/); ………… } </span>这几行代码虽短,逻辑也很简单,但是调用了很多方法。对于canReceiveKeys()函数:
public final boolean canReceiveKeys() { return isVisibleOrAdding() && (mViewVisibility == View.VISIBLE) && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0); }
如果窗口设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE属性,那么该窗口是不能获得焦点的,即canReceiveKeys()会返回false,也就是说焦点窗口是不会更改的。对于悬浮的窗口一般来说是不需要获得焦点的,故一般设置WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE属性,不然会存在一些问题。如果该窗口可以接受key事件(这个key事件有点歧义,并不是只接受按键事件),那么就调用updateFocusedWindowLocked(),这个以后再研究。如果焦点窗口发生变更,那么就调用moveInputMethodWindowsIfNeededLocked(false)来移动输入法窗口到合适的位置。
mInputFocus中保存的窗口在调用InputMonitor.updateInputWindowsLw()时最终设置到InputDispatcher.mFocusedWindowHandle中去了。
2、mInputDispatchFrozen
冻结InputDispatcher标志,“ When true, prevents input dispatch from proceeding until set to false again.”。
①WMS.startFreezingDisplayLocked()-->InputMonitor.freezeInputDispatchingLw()-->mInputDispatchFrozen = true; updateInputDispatchModeLw();
②WMS.stopFreezingDisplayLocked()-->InputMonitor.thawInputDispatchingLw()-->mInputDispatchFrozen = false; updateInputDispatchModeLw();-->InputManagerService.setInputDispatchMode()-->InputDispatcher.setInputDispatchMode(bool enabled, bool frozen)-->mDispatchFrozen = frozen;
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { nsecs_t currentTime = now(); // Reset the key repeat timer whenever we disallow key events, even if the next event // is not a key. This is to ensure that we abort a key repeat if the device is just coming // out of sleep. if (!mPolicy->isKeyRepeatEnabled()) { resetKeyRepeatLocked(); } // If dispatching is frozen, do not process timeouts or try to deliver any new events. if (mDispatchFrozen) { #if DEBUG_FOCUS ALOGD("Dispatch frozen. Waiting some more."); #endif return; } ………. }调用dispatchOnceInnerLocked()分发事件时,直接return掉。上面的调用逻辑可以知道冻结/解冻显示屏时,会冻结InputDispatcher的分发流程。
3、mInputDispatchEnabled
一个java层控制InputDispatcher的开关。
①WMS.setEventDispatching()-->InputMonitor.setEventDispatchingLw()
②WMS.performEnableScreen()-->InputMonitor.setEventDispatchingLw()-->mInputDispatchEnabled = enabled;updateInputDispatchModeLw();-->InputManagerService.setInputDispatchMode()-->InputDispatcher.setInputDispatchMode(bool enabled, bool frozen)-->mDispatchEnabled = enabled;
具体是怎么使能InputDispatcher的?
if (!mDispatchEnabled) { dropReason = DROP_REASON_DISABLED; }在dispatchOnceInnerLocked()中会设置dropReason(放弃原因),如果dropReason不为0表示输入事件将被放弃掉,不会分发。
4、mUpdateInputWindowsNeeded
是否需要更新窗口信息到InputDispatcher中的标志。在非强制性更新窗口信息到InputDispatcher中去时,必须先调用InputMonitor.setUpdateInputWindowsNeededLw()设置该标志,然后再调用InputMonitor.updateInputWindowsLw()。如果强制性更新窗口信息到InputDispatcher中去时就不必设置该变量了。
5、mInputDevicesReadyMonitor
6、mInputDevicesReady
标签:style java for ar art 问题 cti 代码 log
原文地址:http://blog.csdn.net/guoqifa29/article/details/38848409