• Android monkey改造分析 (base uiautomation)


    (1)看monkey就要看它底层如何触发操作,下面列举了几个send MotionEvent 的方法。

    我们可以看到包括monkey和一些自动化框架都是基于什么去操作页面的。

    Send Event

    1.Monkey

    MotionEvent me = getEvent();
    InputManager.getInstance().injectInputEvent(me, 1)

    2.Instrumentation

    Instrumentation inst = new Instrumentation();
    inst.sendPointerSync

    3.Uiautomation

    mUiAutomation.injectInputEvent

    (2)改造

    1.保留monkey的event分发机制

    public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
                long throttle, boolean randomizeThrottle, Display display) {
            // default values for random distributions
            // note, these are straight percentages, to match user input (cmd line
            // args)
            // but they will be converted to 0..1 values before the main loop runs.
            mFactors[FACTOR_TOUCH] = 47.0f;
            mFactors[FACTOR_MOTION] = 10.0f;
            mFactors[FACTOR_TRACKBALL] = 30.0f;
            mFactors[FACTOR_NAV] = 0.0f;
            mFactors[FACTOR_MAJORNAV] = 5.0f;
            mFactors[FACTOR_SYSOPS] = 2.0f;
            mFactors[FACTOR_APPSWITCH] = 0.0f;
            mFactors[FACTOR_FLIP] = 1.0f;
            mFactors[FACTOR_ANYTHING] = 3.0f;
            mFactors[FACTOR_PINCHZOOM] = 2.0f;
    
            mRandom = random;
            mMainApps = MainApps;
            mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
            mDisplay = display;
        }
        private void generateEvents() {
            float cls = mRandom.nextFloat();
            int lastKey = 0;
    
            if (cls < mFactors[FACTOR_TOUCH]) {
                generatePointerEvent(mRandom, GESTURE_TAP);
                return;
            } else if (cls < mFactors[FACTOR_MOTION]) {
                generatePointerEvent(mRandom, GESTURE_DRAG);
                return;
            } else if (cls < mFactors[FACTOR_PINCHZOOM]) {
                generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM);
                return;
            } else if (cls < mFactors[FACTOR_TRACKBALL]) {
                generateTrackballEvent(mRandom);
                return;
            }

    2.由于InputManager在安卓中无法直接调用,所以我们可以用Instrumentation或者Uiautomation去做操作。

    再一步分析Instrumentation的Send Event只能基于app本身去操作(安卓权限问题,如果操作其他应用需要系统权限)

    我们可以直接用uiautomator2.0,通过instrumentation获取Uiautomation

     this.mInstrumentation = instrumentation;
            this.mUiDevice = UiDevice.getInstance(instrumentation);

    调用:

    public boolean injectInputEvent(InputEvent event, boolean sync) {
            synchronized (mLock) {
                throwIfNotConnectedLocked();
            }
            try {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
                }
                // Calling out without a lock held.
                return mUiAutomationConnection.injectInputEvent(event, sync);
            } catch (RemoteException re) {
                Log.e(LOG_TAG, "Error while injecting input event!", re);
            }
            return false;
        }

     3.改进

    1.例如点击区域

    2.点击方式

    3.去掉一些无意义的keyevent

    4.增加一些监听,例如页面死循环监听(图片对比),activity切换监听

  • 相关阅读:
    好文章集合
    WPF:布局
    xcode6.0 模拟器打不开
    vue-vux初学
    【个人笔记】《知了堂》MySQL三种关系:一对一,一对多,多对多。
    vue-axios跨域配置
    vue+webpack使用
    vs code插件
    echarts图表属性设置
    【个人笔记】《知了堂》ajax的get及post请求
  • 原文地址:https://www.cnblogs.com/season-xie/p/6337886.html
Copyright © 2020-2023  润新知