zoukankan      html  css  js  c++  java
  • 第6章7节《MonkeyRunner源代码剖析》Monkey原理分析-事件源-事件源概览-注入按键事件实例

    在事件生成并放入到命令队列后,Monkey类的runMonkeyCycles就会去调用相应事件源的getNextEvent来获的事件来运行事件注入,那么这一小节我们通过MonkeyKeyEvent这个事件的注入方法来看下事件注入过程是怎么样的。

    往系统注入按键事件终于是通过调用InputManager提供的方法来实现的。在Android系统中,按键事件是由InputManager来收集并由WindowManagerService服务来分发给各个Activity处理的,这个系统服务。

    它是用于管理整个系统的输入部分。包括键盘、鼠标、触摸屏等等。所以MonkeyKeyEvent往系统注入按键事件要做的事情就是要准备好InputManager注入事件的方法 injectInputEvent所须要的參数KeyEvent实例。而KeyEvent实例或者用于构建KeyEvent实例所须要用到的參数在MonkeyKeyEvent的成员变量中都有定义:

     27 public class MonkeyKeyEvent
     28   extends MonkeyEvent
     29 {
     30   private int mDeviceId;
     31   private long mEventTime;
     32   private long mDownTime;
     33   private int mAction;
     34   private int mKeyCode;
     35   private int mScanCode;
     36   private int mMetaState;
     37   private int mRepeatCount;
     38   private KeyEvent mKeyEvent;
    代码6-7-1 MonkeyKeyEvent 成员变量

    下面我们先简要描写叙述下各个成员变量的意义。当中大部分变量都是用于构建KeyEvent用的:

    • mDeviceId: 产生该事件的设备ID
    • mEventTime:事件发生事件
    • mDownTime: 按键按下时间。用来推断是点击还是长按
    • mAction: 按键动作,如ACTION_DOWN,ACTION_UP或ACTION_MULTIPLE
    • mKeyCode: 按键键码
    • mScanCode: 按键硬件扫描码
    • mMetatState: 指示哪个元键(如ALT这样的控制类键)在按下状态
    • mRepeatCount:代表按键键码的反复次数
    • mKeyEvent: 系统按键事件。以上的变量在按键事件KeyEvent类中都有相应的变量

    MonkeyKeyEvent支持多个构造函数。当中有两个比較重要。

    调用者能够传入除mKeyEvent外的全部其它变量进行初始化。也能够直接传入一个KeyEvent实例进行初始化。由于刚才说过了KeyEvent里面包括了全部其它变量。我们往下看下者两个构造函数:

    46   public MonkeyKeyEvent(long downTime, long eventTime, int action, int keyCode, int repeatCount, int metaState, int device, int scan    Code)
     47   {
     48     super(0);
     49     this.mDownTime = downTime;
     50     this.mEventTime = eventTime;
     51     this.mAction = action;
     52     this.mKeyCode = keyCode;
     53     this.mRepeatCount = repeatCount;
     54     this.mMetaState = metaState;
     55     this.mDeviceId = device;
     56     this.mScanCode = scanCode;
     57   }
     58 
     59   public MonkeyKeyEvent(KeyEvent e) {
     60     super(0);
     61     this.mKeyEvent = e;
     62   }
    代码6-7-2 MonkeyKeyEvent构造函数

    在准备好注入事件所须要的提供的信息后,下一步就须要去看下MonkeyKeyEvent的注入事件这种方法是怎么实现的了:

     99     @Override
    100     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
    101         if (verbose > 1) {
    102             String note;
    103             if (mAction == KeyEvent.ACTION_UP) {
    104                 note = "ACTION_UP";
    105             } else {
    106                 note = "ACTION_DOWN";
    107             }
    108 
    109             try {
    110                 System.out.println(":Sending Key (" + note + "): "
    111                         + mKeyCode + "    // "
    112                         + MonkeySourceRandom.getKeyName(mKeyCode));
    113             } catch (ArrayIndexOutOfBoundsException e) {
    114                 System.out.println(":Sending Key (" + note + "): "
    115                         + mKeyCode + "    // Unknown key event");
    116             }
    117         }
    118 
    119         KeyEvent keyEvent = mKeyEvent;
    120         if (keyEvent == null) {
    121             long eventTime = mEventTime;
    122             if (eventTime <= 0) {
    123                 eventTime = SystemClock.uptimeMillis();
    124             }
    125             long downTime = mDownTime;
    126             if (downTime <= 0) {
    127                 downTime = eventTime;
    128             }
    129             keyEvent = new KeyEvent(downTime, eventTime, mAction, mKeyCode,
    130                     mRepeatCount, mMetaState, mDeviceId, mScanCode,
    131                     KeyEvent.FLAG_FROM_SYSTEM, InputDevice.SOURCE_KEYBOARD);
    132         }
    133         if (!InputManager.getInstance().injectInputEvent(keyEvent,
    134             InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT)) {
    135             return MonkeyEvent.INJECT_FAIL;
    136         }
    137         return MonkeyEvent.INJECT_SUCCESS;
    138     }
    139 }
    代码6-7-3 MonkeyKeyEvent - injectEvent

    • 103-107行: 确定这个按键事件是按下事件还起弹起事件
    • 119-132行: 假设MonkeyKeyEvent是用KeyEvent构造的,那么直接使用这个KeyEvent。假设不是用KeyEvent而是用另外一个构造函数构造的,那么用该构造函数传进来的全部參数来构造一个KeyEvent来使用
    • 133-134行: 通过调用InputManager来把按键keyEvent注入到系统窗体里面来实现注入一个按键事件的操作。


    注:很多其它文章请关注公众号:techgogogo或个人博客http://techgogogo.com。当然,也很欢迎您直接微信(zhubaitian1)勾搭。本文由天地会珠海分舵原创。转载请自觉。是否投诉维权看心情。


  • 相关阅读:
    设计模式的四个基本要素
    拖拉记录上下移动--Ajax UI
    Rails-Treasure chest2 嵌套表单;
    YAML(摘录)
    Rails-Treasure chest1 (自定义Model网址;多语言包; 时区设置, TimeZone类; 格式日期时间; 表单单选UI; 表单多选UI;Select2 Plugin)
    iTerm2的设置和Zsh.
    **优化--后端**: 计数缓存counter_cache; rack-mini-profiler(2300🌟) ; bullet(5000✨):侦测N+1query
    优化--前端(全占课,未完成作业:);CDN; Http/2的设置(未完成)
    null值的判断
    if else
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7080605.html
Copyright © 2011-2022 走看看