Android应用程序键盘(Keyboard)消息处理机制分析(21)

简介:

   Step 30. ViewRoot.dispatchFinishedEvent

         这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. public final class ViewRoot extends Handler implements ViewParent,  
  2.         View.AttachInfo.Callbacks {  
  3.     ......  
  4.   
  5.     public void dispatchFinishedEvent(int seq, boolean handled) {  
  6.         Message msg = obtainMessage(FINISHED_EVENT);  
  7.         msg.arg1 = seq;  
  8.         msg.arg2 = handled ? 1 : 0;  
  9.         sendMessage(msg);  
  10.     }  
  11.   
  12.     ......  
  13. }  

        和前面的Step 26一样,ViewRoot不是直接处理这个键盘事件,而是把它作为一个消息(FINISHED_EVENT)放在消息队列中去,最后,这个消息由ViewRoot的handleFinishedEvent函数来处理。       Step 31. ViewRoot.handleFinishedEvent

         这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. public final class ViewRoot extends Handler implements ViewParent,  
  2.         View.AttachInfo.Callbacks {  
  3.     ......  
  4.   
  5.     void handleFinishedEvent(int seq, boolean handled) {  
  6.         final KeyEvent event = (KeyEvent)retrievePendingEvent(seq);  
  7.         ......  
  8.   
  9.         if (event != null) {  
  10.             final boolean sendDone = seq >= 0;  
  11.             if (!handled) {  
  12.                 deliverKeyEventToViewHierarchy(event, sendDone);  
  13.                 return;  
  14.             } else if (sendDone) {  
  15.                 ......  
  16.             } else {  
  17.                 ......  
  18.             }  
  19.         }  
  20.     }  
  21.   
  22.     ......  
  23. }  

        如果InputMethodManager没有处理这个键盘事件,那么ViewRoot就会调用deliverKeyEventToViewHierarchy函数来把这个键盘事件分发给当前激活的Activity窗口来处理。

        Step 32. ViewRoot.deliverKeyEventToViewHierarchy

        这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:

  1. public final class ViewRoot extends Handler implements ViewParent,  
  2.         View.AttachInfo.Callbacks {  
  3.     ......  
  4.   
  5.     private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {  
  6.         try {  
  7.             if (mView != null && mAdded) {  
  8.                 ......  
  9.   
  10.                 boolean keyHandled = mView.dispatchKeyEvent(event);  
  11.             }  
  12.   
  13.             ......  
  14.         } finally {  
  15.             if (sendDone) {  
  16.                 finishInputEvent();  
  17.             }  
  18.         }  
  19.     }  
  20.   
  21.     ......  
  22. }  

        这个函数首先会调用ViewRoot类的成员变量mView的dispatchKeyEvent来处理这个键盘事件,然后最调用ViewRoot类的finishInputEvent来处理手尾工作。

        ViewRoot类的成员变量mView的类型为DecorView,它是由ActivityThread类第一次Resume当前的Activity窗口时创建的,具体可以参考ActivityThread类的handleResumeActivity成员函数,这里就不关注了。

  Step 33. DecorView.dispatchKeyEvent

        这个函数定义在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java文件中,它是PhoneWindow类的一个内部类:

  1. public class PhoneWindow extends Window implements MenuBuilder.Callback {  
  2.     ......  
  3.   
  4.     private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {  
  5.         ......  
  6.   
  7.         @Override  
  8.         public boolean dispatchKeyEvent(KeyEvent event) {  
  9.             ......  
  10.   
  11.             final Callback cb = getCallback();  
  12.             final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)  
  13.                 : super.dispatchKeyEvent(event);  
  14.   
  15.             ......  
  16.         }  
  17.   
  18.         ......  
  19.     }  
  20.   
  21.     ......  
  22. }  
        这里通过getCallback函数返回的是当前应用程序的激活的Activity窗口的Window.Callback接口,一般它不为NULL,因此,这个函数会调用Activity类的dispatchKeyEvent来处理这个键盘事件。
        Step 34. Activity.dispatchKeyEvent

 

        这个函数定义在frameworks/base/core/java/android/app/Activity.java文件中:

  1. public class Activity extends ContextThemeWrapper  
  2.         implements LayoutInflater.Factory,  
  3.         Window.Callback, KeyEvent.Callback,  
  4.         OnCreateContextMenuListener, ComponentCallbacks {  
  5.     ......  
  6.   
  7.     public boolean dispatchKeyEvent(KeyEvent event) {  
  8.         ......  
  9.   
  10.         View decor = mDecor;  
  11.         if (decor == null) decor = win.getDecorView();  
  12.         return event.dispatch(this, decor != null  
  13.             ? decor.getKeyDispatcherState() : nullthis);  
  14.     }  
  15.   
  16.     ......  
  17. }  
         这里,Activity不是直接处理这个键盘事件,而是通过KeyEvent的dispatch转发一下。注意,KeyEvent的成中函数dispatch的第一个参数的类型是KeyEvent.Callback,而Activity实现了这个接口,因此,这里可以传this引用过去。

 

         Step 35. KeyEvent.dispatch

         这个函数定义在frameworks/base/core/java/android/view/KeyEvent.java文件中:

  1. public class KeyEvent extends InputEvent implements Parcelable {  
  2.     ......  
  3.   
  4.     public final boolean dispatch(Callback receiver, DispatcherState state,  
  5.             Object target) {  
  6.         switch (mAction) {  
  7.         case ACTION_DOWN: {  
  8.             ......  
  9.             boolean res = receiver.onKeyDown(mKeyCode, this);  
  10.             ......  
  11.             return res;  
  12.         }  
  13.         case ACTION_UP:  
  14.             ......  
  15.             return receiver.onKeyUp(mKeyCode, this);  
  16.         case ACTION_MULTIPLE:  
  17.             final int count = mRepeatCount;  
  18.             final int code = mKeyCode;  
  19.             if (receiver.onKeyMultiple(code, count, this)) {  
  20.                 return true;  
  21.             }  
  22.             ......  
  23.             return false;  
  24.         }  
  25.         return false;  
  26.     }  
  27.   
  28.     ......  
  29. }  
         这里就根据一个键是按下(ACTION_DOWN)、还是松开(ACTION_UP)或者是一个相同的键被多次按下和松开(ACTION_MULTIPLE)等不同事件类型来分别调用Activity的onKeyDown、onKeyUp和onKeyMultiple函数了。
         Activity窗口处理完这个键盘事件后,层层返回,最后回到Step 32中,调用finishInputEvent事件来处理一些手尾工,下面我们将会看到这些手尾工是什么。




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966644,如需转载请自行联系原作者
目录
相关文章
|
2天前
|
移动开发 API Android开发
构建高效Android应用:Kotlin协程的实践指南
【5月更文挑战第11天】 在移动开发领域,性能优化和资源管理是至关重要的。特别地,对于Android开发者来说,合理利用Kotlin协程可以极大地改善应用的响应性和稳定性。本文将深入探讨Kotlin协程在Android中的实际应用,包括它们如何简化异步编程模型、提高UI线程的响应性,以及减少内存消耗。我们将通过具体案例分析,了解如何在实际项目中有效地使用协程,从而帮助开发者构建更加高效的Android应用程序。
|
2天前
|
Android开发
Android应用实例(一)之---有道辞典VZ.0
Android应用实例(一)之---有道辞典VZ.0
11 2
|
22小时前
|
存储 API Android开发
Android 11 中的存储机制更新,面试心得体会
Android 11 中的存储机制更新,面试心得体会
|
1天前
|
安全 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【5月更文挑战第16天】 在移动开发领域,性能一直是开发者关注的焦点。随着Kotlin语言的普及,其与Java在Android应用中的性能表现成为热门话题。本文将深入分析Kotlin和Java在Android平台上的性能差异,并通过实际测试数据来揭示二者在编译速度、应用启动时间以及运行效率方面的表现。我们的目标是为开发者提供一个参考依据,以便在选择合适的编程语言时做出更加明智的决策。
|
2天前
|
缓存 移动开发 Android开发
Android 应用性能优化实践
【5月更文挑战第15天】 在移动开发领域,应用的性能直接关系到用户体验和产品的市场表现。特别是对于安卓平台,设备的多样性和应用生态环境的复杂性使得性能优化成为开发者的一项重要技能。本文将深入探讨针对安卓应用的性能瓶颈识别、分析方法以及具体的优化策略,旨在为开发者提供一套实用的性能提升解决方案。
|
2天前
|
移动开发 测试技术 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【5月更文挑战第15天】 在移动开发领域,一个成功的Android应用不仅需要具备吸引用户的功能,更应提供流畅和高效的用户体验。随着技术的不断进步,开发者面临着将先进技术集成到现有架构中以提高应用性能的挑战。本文将深入探讨如何通过最新的Android框架和工具来优化应用性能,包括对UI的响应性、内存管理以及多线程处理等关键方面的改进,旨在帮助开发者构建出更加强大、快速且稳定的Android应用。
|
2天前
|
缓存 Android开发 UED
构建高效Android应用:从优化用户体验到提升性能
【5月更文挑战第15天】 在移动开发领域,构建一个高效的Android应用不仅仅意味着实现功能,还要确保流畅的用户体验和出色的性能。本文将深入探讨如何通过界面优化、代码整洁、资源管理和多线程处理等技术手段来提升Android应用的整体效率。我们将透过实际案例,揭示常见性能瓶颈的成因,并提供相应的解决方案。此外,文章还会涵盖最新的Android Studio工具和Lint检查的使用,帮助开发者早期发现潜在问题。
|
2天前
|
缓存 Java Android开发
Android应用性能优化实战
【5月更文挑战第14天】 在竞争激烈的应用市场中,一个流畅、高效的应用能显著提升用户体验并增强用户黏性。本文深入探讨了针对安卓平台进行应用性能优化的策略与实践,从内存管理到多线程处理,再到布局渲染和网络请求的优化,旨在为开发者提供一套全面的优化工具箱。通过分析常见的性能瓶颈并结合最新的Android技术动态,我们不仅讨论理论,还将分享具体的代码示例和改进方法,帮助开发者在实际应用中实现性能提升。
|
2天前
|
移动开发 数据处理 Android开发
构建高效Android应用:Kotlin协程的实践与优化策略
【5月更文挑战第14天】在移动开发领域,性能优化和资源管理是提升用户体验的关键因素之一。随着Kotlin语言的普及,其异步编程解决方案——协程,已经成为Android开发者手中的强大工具。本文将深入探讨Kotlin协程在Android应用中的实践方法,分析其在处理异步任务时带来的优势,并提出一系列优化策略,帮助开发者构建更加高效、响应迅速的Android应用。通过具体案例分析和性能对比,我们将展示如何充分利用协程来简化代码结构,提高应用性能,并确保用户界面的流畅性。
|
2天前
|
移动开发 数据库 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第14天】在移动开发领域,性能优化和流畅的用户体验始终是开发者追求的目标。随着Kotlin语言的兴起,其提供的协程特性为Android应用带来了革新性的异步编程解决方案。本文将深入探讨Kotlin协程的核心优势,并结合实际案例分析如何在Android应用中有效地利用协程来提升性能和响应性,同时保证代码的简洁性和可维护性。