本文共 4477 字,大约阅读时间需要 14 分钟。
Step 2. ViewRoot.requestLayout 这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中: - public final class ViewRoot extends Handler implements ViewParent,
- View.AttachInfo.Callbacks {
- ......
-
- public void requestLayout() {
- ......
- mLayoutRequested = true;
- scheduleTraversals();
- }
-
- ......
- }
这个函数调用了scheduleTraversals函数来进一步执行操作,由于篇幅关系,我们就不详细描述scheduleTraversals函数了,简单来说,在scheduleTraversals函数中,会通过sendEmptyMessage(DO_TRAVERSAL)发送一个消息到应用程序的消息队列中,这个消息最终由ViewRoot的handleMessage函数处理,而ViewRoot的handleMessage函数把这个消息交给ViewRoot类的performTraversals来处理,在performTraversals函数中,又会调用ViewRoot类的relayoutWindow函数来进一步执行操作,最后在relayoutWindow函数中,就会通过WindowManagerService内部类Session的远程接口sWindowSession的relayout函数来进入到WindowManagerService中。 Step 3. WindowManagerService.Session.relayout 这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java 文件中: - public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
-
- private final class Session extends IWindowSession.Stub
- implements IBinder.DeathRecipient {
- ......
-
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
- int requestedWidth, int requestedHeight, int viewFlags,
- boolean insetsPending, Rect outFrame, Rect outContentInsets,
- Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
-
- int res = relayoutWindow(this, window, attrs,
- requestedWidth, requestedHeight, viewFlags, insetsPending,
- outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
-
- return res;
- }
-
- ......
- }
-
- ......
- }
这个函数只是简单地调用WindowManagerService的成员函数relayoutWIndow来进一步处理。 Step 4. WindowManagerService.relayoutWIndow 这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java 文件中: - public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
-
- public int relayoutWindow(Session session, IWindow client,
- WindowManager.LayoutParams attrs, int requestedWidth,
- int requestedHeight, int viewVisibility, boolean insetsPending,
- Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
- Configuration outConfig, Surface outSurface) {
- ......
-
- synchronized(mWindowMap) {
- ......
-
- mInputMonitor.updateInputWindowsLw();
- }
-
- ......
- }
-
- ......
- }
这个函数又会继续调用mInputMonitor的updateInputWindowsLw成员函数来更新当前的输入窗口,mInputMonitor是WindowManagerService的成员变量,它的类型为InputMonitor。 Step 5. InputMonitor.updateInputWindowsLw 这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java 文件中: - public class WindowManagerService extends IWindowManager.Stub
- implements Watchdog.Monitor {
- ......
-
- final class InputMonitor {
- ......
-
-
- public void updateInputWindowsLw() {
-
-
-
-
-
- final ArrayList<WindowState> windows = mWindows;
- final int N = windows.size();
- for (int i = N - 1; i >= 0; i--) {
- final WindowState child = windows.get(i);
- if (child.mInputChannel == null || child.mRemoved) {
-
- continue;
- }
-
- ......
-
-
- final InputWindow inputWindow = mTempInputWindows.add();
-
- ......
- }
-
-
- mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
-
- ......
- }
-
- ......
- }
-
- ......
- }
这个函数将当前系统中带有InputChannel的Activity窗口都设置为InputManager的输入窗口,但是后面我们会看到,只有当前激活的窗口才会响应键盘消息。 Step 6. InputManager.setInputWindows 这个函数定义在frameworks/base/services/java/com/android/server/InputManager.java文件中: - public class InputManager {
- ......
-
- public void setInputWindows(InputWindow[] windows) {
- nativeSetInputWindows(windows);
- }
-
- ......
- }
这个函数调用了本地方法nativeSetInputWindows来进一步执行操作。
Step 7. InputManager.nativeSetInputWindows 这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp 文件中: - static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
- jobjectArray windowObjArray) {
- if (checkInputManagerUnitialized(env)) {
- return;
- }
-
- gNativeInputManager->setInputWindows(env, windowObjArray);
- }
这里的gNativeInputManager我们前面分析InputManager的启动过程时已经见过了,这是一个本地InputManager对象,通过它进一步设置当前系统的输入窗口。
转载地址:http://oagho.baihongyu.com/