Step 2.ViewRoot.requestLayout 这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
  1. publicfinalclassViewRootextendsHandlerimplementsViewParent,
  2. View.AttachInfo.Callbacks{
  3. ......
  4. publicvoidrequestLayout(){
  5. ......
  6. mLayoutRequested=true;
  7. scheduleTraversals();
  8. }
  9. ......
  10. }
这个函数调用了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文件中:
  1. publicclassWindowManagerServiceextendsIWindowManager.Stub
  2. implementsWatchdog.Monitor{
  3. ......
  4. privatefinalclassSessionextendsIWindowSession.Stub
  5. implementsIBinder.DeathRecipient{
  6. ......
  7. publicintrelayout(IWindowwindow,WindowManager.LayoutParamsattrs,
  8. intrequestedWidth,intrequestedHeight,intviewFlags,
  9. booleaninsetsPending,RectoutFrame,RectoutContentInsets,
  10. RectoutVisibleInsets,ConfigurationoutConfig,SurfaceoutSurface){
  11. //Log.d(TAG,">>>>>>ENTEREDrelayoutfrom"+Binder.getCallingPid());
  12. intres=relayoutWindow(this,window,attrs,
  13. requestedWidth,requestedHeight,viewFlags,insetsPending,
  14. outFrame,outContentInsets,outVisibleInsets,outConfig,outSurface);
  15. //Log.d(TAG,"<<<<<<EXITINGrelayoutto"+Binder.getCallingPid());
  16. returnres;
  17. }
  18. ......
  19. }
  20. ......
  21. }

这个函数只是简单地调用WindowManagerService的成员函数relayoutWIndow来进一步处理。 Step 4.WindowManagerService.relayoutWIndow 这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
  1. publicclassWindowManagerServiceextendsIWindowManager.Stub
  2. implementsWatchdog.Monitor{
  3. ......
  4. publicintrelayoutWindow(Sessionsession,IWindowclient,
  5. WindowManager.LayoutParamsattrs,intrequestedWidth,
  6. intrequestedHeight,intviewVisibility,booleaninsetsPending,
  7. RectoutFrame,RectoutContentInsets,RectoutVisibleInsets,
  8. ConfigurationoutConfig,SurfaceoutSurface){
  9. ......
  10. synchronized(mWindowMap){
  11. ......
  12. mInputMonitor.updateInputWindowsLw();
  13. }
  14. ......
  15. }
  16. ......
  17. }
这个函数又会继续调用mInputMonitor的updateInputWindowsLw成员函数来更新当前的输入窗口,mInputMonitor是WindowManagerService的成员变量,它的类型为InputMonitor。 Step 5.InputMonitor.updateInputWindowsLw 这个函数定义在frameworks/base/services/java/com/android/server/WindowManagerService.java文件中:
  1. publicclassWindowManagerServiceextendsIWindowManager.Stub
  2. implementsWatchdog.Monitor{
  3. ......
  4. finalclassInputMonitor{
  5. ......
  6. /*Updatesthecachedwindowinformationprovidedtotheinputdispatcher.*/
  7. publicvoidupdateInputWindowsLw(){
  8. //Populatetheinputwindowlistwithinformationaboutallofthewindowsthat
  9. //couldpotentiallyreceiveinput.
  10. //Asanoptimization,wecouldtrytoprunethelistofwindowsbutthisturns
  11. //outtobedifficultbecauseonlythenativecodeknowsforsurewhichwindow
  12. //currentlyhastouchfocus.
  13. finalArrayList<WindowState>windows=mWindows;
  14. finalintN=windows.size();
  15. for(inti=N-1;i>=0;i--){
  16. finalWindowStatechild=windows.get(i);
  17. if(child.mInputChannel==null||child.mRemoved){
  18. //Skipthiswindowbecauseitcannotpossiblyreceiveinput.
  19. continue;
  20. }
  21. ......
  22. //Addawindowtoourlistofinputwindows.
  23. finalInputWindowinputWindow=mTempInputWindows.add();
  24. ......
  25. }
  26. //Sendwindowstonativecode.
  27. mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
  28. ......
  29. }
  30. ......
  31. }
  32. ......
  33. }
这个函数将当前系统中带有InputChannel的Activity窗口都设置为InputManager的输入窗口,但是后面我们会看到,只有当前激活的窗口才会响应键盘消息。 Step 6.InputManager.setInputWindows 这个函数定义在frameworks/base/services/java/com/android/server/InputManager.java文件中:
  1. publicclassInputManager{
  2. ......
  3. publicvoidsetInputWindows(InputWindow[]windows){
  4. nativeSetInputWindows(windows);
  5. }
  6. ......
  7. }
这个函数调用了本地方法nativeSetInputWindows来进一步执行操作。
Step 7.InputManager.nativeSetInputWindows
这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp文件中:
  1. staticvoidandroid_server_InputManager_nativeSetInputWindows(JNIEnv*env,jclassclazz,
  2. jobjectArraywindowObjArray){
  3. if(checkInputManagerUnitialized(env)){
  4. return;
  5. }
  6. gNativeInputManager->setInputWindows(env,windowObjArray);
  7. }
这里的gNativeInputManager我们前面分析InputManager的启动过程时已经见过了,这是一个本地InputManager对象,通过它进一步设置当前系统的输入窗口。

更多相关文章

  1. android之针对fragment多次调用onCreateView的问题
  2. Android应用程序组件Content Provider的共享数据更新通知机制分
  3. Android高手进阶教程(二十七)之---基于ViewFlipper实现的自定义
  4. How to destroy an Activity in android
  5. How to destroy an Activity in android
  6. Android中获取屏幕信息DisplayMetrics的用法
  7. Android应用程序键盘(Keyboard)消息处理机制分析(21)
  8. Android(安卓)中自定义View的应用
  9. Android(安卓)Universal Image Loader 源码分析

随机推荐

  1. Google Android's Gingerbread Update Co
  2. [zt]获取android联系人信息
  3. FloatingActionButton
  4. [Android(安卓)GMS 认证] CTS 问题列表之
  5. Android(安卓)Manifest 用法
  6. 【Android】【绘图】绘制波浪线动画
  7. Android中倒计时代码
  8. android 配置文件
  9. android 判断APP是否第一次打开
  10. 《Android(安卓)基础(三十三)》 TabHost ~