Android入门之把窗口信息传递给InputDispatcher
分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
当窗口信息变化时,就应该把变化后的窗口信息传递给InputDispatcher,所以,从“什么时候会改变窗口信息入手”,这些变化的可能有:
(1) 窗口大小发生变化时;
(2) 窗口从显示变为隐藏,或隐藏变为显示时;
(3) 暂停或恢复对消息的处理时;
(4) 窗口层值发生变化时;
(5) 添加或删除窗口时;
这当然只是其中一部分,根据这个思路,在WindowManagerService中寻找对应的方法,柯先生总结有以下方法:
调用updateInputWindowsLw的方法 | 描述 |
removeWindowInnerLocked() | 删除窗口 |
relayoutWindow() | 重新对窗口进行排级 |
removeWindowToken() | 删除窗口 |
setTokenVisibilityLocked() | 改变窗口的显示状态 |
InputMonitor.setInputFocusLw() | 设置某个窗口为消息输入的对象窗口 |
InputMonitor.pauseDispatchingLw() | 暂停指定窗口接收用户消息 |
InputMonitor.resumeDispatchingLw() | 恢复指定窗口继续接收用户消息 |
performLayoutLockedInner() | 对窗口重新进行排版 |
在addWindow分析中说过,添加窗口是调用了performLayoutLockedInner方法实现将信息传递给InputDispatcher的。
接下来继续分析信息是如何写入InputDispatcher的。
不难发现,上述方法的共性是都调用了InputMonitor的updateInputWindowLw(),我们主要关注该方法中的以下代码:
- mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
跟进去,在InputManager中又调用了com_android_server_InputManager.cpp的本地方法:
- public void setInputWindows(InputWindow[] windows) {
- nativeSetInputWindows(windows);
- }
nativeSetInputWindows方法代码如下所示:
- void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
- Vector<InputWindow> windows;
- jsize length = env->GetArrayLength(windowObjArray);
- for (jsize i = 0; i < length; i++) {
- jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
- if (! inputTargetObj) {
- break; // found null element indicating end of used portion of the array
- }
- windows.push();
- InputWindow& window = windows.editTop();
- bool valid = populateWindow(env, inputTargetObj, window);
- if (! valid) {
- windows.pop();
- }
- env->DeleteLocalRef(inputTargetObj);
- }
- mInputManager->getDispatcher()->setInputWindows(windows);
- }