DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
来源:互联网 发布:r230搓纸轮 淘宝 编辑:程序博客网 时间:2024/04/29 11:40
Activity的setDefaultKeyMode (int mode) 方法用来设置一个Activity的默认的按键模式。
具体介绍可以参见我写的 setDefaultKeyMode 用法介绍 一文。地址是: http://blog.csdn.net/silenceburn/archive/2010/12/11/6069645.aspx
其中有一种模式是 DEFAULT_KEYS_SHORTCUT ,本文从API文档对此模式的介绍出发,首先通过编写示例代码,介绍其功能用法,然后通过追踪源码,简单介绍此模式在android源码中是如何实现的。
1. 关于 DEFAULT_KEYS_SHORTCUT 的 API文档介绍
Use with setDefaultKeyMode(int) to execute a menu shortcut in default key handling.That is, the user does not need to hold down the menu key to execute menu shortcuts. 从字面上看,其含义是指,将默认的按键输入作为菜单快捷键进行处理。也就是说,用户不需要按下menu按键,就可以处理菜单快捷键,听起来非常神奇,究竟是不是这样呢?
2.编写示例程序
我们编写一个程序验证一下其功能,首先新建一个工程,并设置默认按键模式为 DEFAULT_KEYS_SHORTCUT
为默认的main.xml中的TextView增加一个id属性,之后我们会用菜单选项控制这行字的颜色
使用findViewById获取上一步中定义了id的文本对象,将其引用保存在成员变量b中。重写onPrepareOptionsMenu方法,增加我们自己的菜单项,并注册快捷键,同时增加菜单点击的响应事件。
注意我们一共注册了两个菜单项,一个叫“One”,点击时将文本对象 b 的背景颜色改为红色,同时定义其快捷键为0一个叫“Two”,点击时将文本对象 b 的背景颜色改为绿色,同时定义其快捷键为1 至此示例程序完成。
3.验证使用示例程序
启动AVD,运行上述程序,程序启动后,我们应当看到是黑底灰字,点击menu按钮,可以看到One和Two两个菜单选项。如下图所示:
目前Menu是打开状态,点击One ,将把“helloworld...”字样的背景色变为红色,点击Two ,将把“helloworld...”字样的背景色变为红绿色。或者我们点设置好的快捷键 0 和 1,发现可以直接调用菜单选项控制颜色变化。
到目前为止一切都很正常,不过,神奇的现在来了! 我们首先关闭菜单,然后直接点键盘键"0“,看看会发生什么。再直接点键盘键"1" ,看看会发生什么。哈哈,在没有激活菜单的情况下,菜单项快捷键被直接调用了!根本不需要打开菜单,就可以用激活菜单快捷键!
什么?有位同学说快捷键就应该是这样子把,那好,请你把 onCreate 里面的setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 改为 setDefaultKeyMode(DEFAULT_KEYS_DISABLE);然后再运行试试,在不打开菜单的情况下,你就是把 0 和 1 按坏,系统也不会理你的呵呵
4.浅析实现原理
那么这神奇的功能是如何实现的呢?我们试着通过分析android源码找到答案。 首先顺藤摸瓜,我们找一找系统是如何处理 DEFAULT_KEYS_SHORTCUT 关键字的,在Activity.java中可以找到如下代码片段:由此可知,当系统检测到 DEFAULT_KEYS_SHORTCUT 关键字时,实际调用了getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,keyCode, event,Menu.FLAG_ALWAYS_PERFORM_CLOSE) 我们继续追寻,但是这里会遇到一个困难,就是查阅API文档你会发现,performPanelShortcut函数是个纯虚函数!接下来该怎么办呢?既然功能顺利执行了,那么这个纯虚函数一定会有一个实现的。这个实现类必然是window类的子类。所以我们在OnCreate里面加上一行代码 Window w = this.getWindow();然后通过Eclipse的调试器,利用RTTI查看其实现类,结果如下图:
可以看的很清楚,实现类是 PhoneWindow ,这样我们就可以到 PhoneWindow 的源码中去查找performPanelShortcut的实现了。 在PhoneWindow.java中我们可以看到如下代码片段:
终于看到menu字样了,这里我们可以看到 if 里面描述的调用条件,首先当前panel必须已经准备好了(你可以用 onPreparePanel 截获到准备请求),其次,当前panel必须是有Menu的!(st.menu != null),从这里我们可以明白DEFAULT_KEYS_SHORTCUT对于没有menu的应用是没有任何效果的。而且在另一处代码我们会看到还要进行 isShortCut 的判断,所以对于没有快捷键的菜单也是没有任何效果的。 那么我们再看看 preparePanel 里面是如何实现的,在其实现中可以找到如下代码片段:
至此,就完全明白了!代码在这里回调了 onPreparePanel ,而 onPreparePanel 中会回调 onPrepareOptionsMenu ,而onPrepareOptionsMenu ,就是我们自己写实现自定义菜单的地方了。 为了验证上述推导,我们在onPrepareOptionsMenu 中放入断点,然后在菜单关闭的情况下,输入快捷键,运行到断点后查看调用堆栈,入下图所示:
堆栈调用顺序可以很清楚的看出我们的推导过程是正确的。至此 DEFAULT_KEYS_SHORTCUT 的实现分析完毕。
总结: 我之所以非常喜爱和看好android平台,就是因为她是开源的,当我们对任何一个问题有疑问时,都可以把她扒光了细看,呵呵。而apple的IOS,尽管你很美,但是你的内心实在太难捉摸了。 从本文的分析过程可以看出,平台任何一个看似神奇的功能的实现,背后都有安卓源码开发者们大巧不工重剑无锋的的实现。 本文对DEFAULT_KEYS_SHORTCUT的分析实际上是很浅显的,如果细看源码,会发现更多的有意思的地方的。
0 0
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT) 功能的验证 及其 源码实现分析
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- Java____Timer实现定时功能及其源码研究
- RegularExpressionValidator验证控件时的验证功能及其验证表达式
- 串及其功能的实现
- 验证码功能的实现
- 验证码功能的实现
- 验证码功能的实现
- 验证码的功能实现
- 验证码的功能实现
- 奇数幻方的实现及其验证
- 参照JDK源码实现一个LinkedList,分析常用的List集合及其适用场景
- Spring源码分析之ProxyFactoryBean方式实现Aop功能的分析
- 摇一摇功能及其动画的实现
- 双循环链表的实现及其功能!!!
- 双链表的实现及其功能大全!!!
- linux下tar命令
- iPhone 6s玫瑰金版怎么样
- 读书笔记——《程序员自我修养》——目标文件
- Android Studio
- Layout_weight这个属性
- DEFAULT_KEYS_SHORTCUT 功能的验证 及其 源码实现分析
- 多任务----同步
- JavaScript高级程序设计之面向对象的程序设计之继承之寄生式继承第6.3.5讲笔记
- Struts2 四、Struts2 处理流程
- [思路题] hdu 5491 The Next
- android中build过程
- 【python】matplotlib在windows10 和win7下安装
- 类中静态成员函数的使用
- 二维码扫描设置