最近在状态栏上面添加了一些系统常用的按键,用的比较多的,Home, Menu, Back三个按键,

分别模拟物理按键按下时的消息,

参考下面两篇文章,可以实现在状态栏上添加自定义的按键,

1.

在android的状态栏(statusbar)中增加menu,home和back快捷键的方法

http://blogold.chinaunix.net/u2/78893/showart_2349971.html

2.

在android的状态栏(statusbar)中增加menu,home和back快捷键的方法,及按键延迟原因分析

http://hi.baidu.com/tigerpan/blog/item/63caae81b57580b16c811937.html

但是在状态栏上面点击按钮的时候,却经常出现死锁,假死的情况,在第二篇文章的时候,提到,

我们先看一下执行流程
在com.android.server.WindowManagerService.injectKeyEvent(KeyEvent, boolean)函数中我们可以看到实际上是调用dispatchKey(newEvent, pid, uid)函数,这个dispatchKey函数中:

需要先找到当前的焦点focusObj(focusObj:WindowState 就是在维护窗口ViewRoot与WindowManagerService之前的关联,这二者的通信都在WindowState中可以找到);再用focusObj把KeyEvent传递给当前焦点窗口。但在传递之前会先调用mKeyWaiter.waitForNextEventTarget()函数等待当前焦点处理完上一次事件(这包括KeyEvent,MotionEvent...等),如何判断是否处理完上一次事件, 用if (mFinished && !mDisplayFrozen) if (targetWin != null)这两个if语句判断,而最关键就是这个mFinished ,这里还得查看ViewRoot,在ViewRoot中分发事件后会调用sWindowSession.finishKey(mWindow);告诉WindowManagerService,在doFinishedKeyLocked()函数中将mFinished = true,如果mFinished不为true,则会wait(curTimeout),这就是出现停顿的直接原因

通过打印Log显示是我们的KeyEvent.Action_Down事件一直不能mFinished,这就要跟踪ViewRoot,发现每次在模拟的KeyEvent.Action_Down事件的Message根本不能被处理,原因是StatusBarView的TouchEvent没有处理完成,并且与模拟的KeyEvent.Action_Down事件在MessageQueue的next函数中卡住了而ViewRoot本身就是一个Handler,大量的Message从此经过,而StatusBar的ViewRoot既要处理Touch事件也要处理模拟按键,就出现了这种竞态死锁的现象。

延迟发送模拟的KeyEvent是我目前采用的解决方式,上面的例子中sendKey函数已经体现

大概就是按键点击的时候(我自己个人理解),如果在onClick事件里面立刻直接发送KeyEvent的话,会导致onClick的消息处理无法正常返回,从而导致后面的消息也无法被获取处理,这是产生假死停顿的原因,所以参考上面的方法,新创建一个线程,延时发送KeyEvent(我直接用文2的方法问题也没有得到很好的解决).

更多相关文章

  1. C语言函数的递归(上)
  2. 转自 老罗 Android应用程序资源管理器(Asset Manager)的创建过程分
  3. Android(安卓)事件分发源码分析
  4. Android:Activity与Fragment通信(99%)完美解决方案
  5. [置顶] Android触摸事件分发
  6. 针对 CoordinatorLayout 及 Behavior 的一次细节较真
  7. Android(安卓)RxJava:功能性操作符 全面讲解
  8. Android开发小技巧 | 一句命令搞定截屏
  9. Mediaplayer中通过create函数获取资源时PreareAsync问题

随机推荐

  1. android ADB PUSH 安装apk的具体步骤 及
  2. android kernel Debugging hibernation a
  3. android读取SDCard任意路径下的文件
  4. android 判断时间是否已过期
  5. Android(安卓)系统 设置 之 网络 APN (一)
  6. Android(安卓)之 发送邮件
  7. 使用android快速开发框架afinal 开发andr
  8. Android判断应用是否存在
  9. Android中多层Fragment嵌套,调用相册返回U
  10. TextView在xml里配置onclick事件