手机自动化测试:appium源码分析之bootstrap十四

手机自动化测试:appium源码分析之bootstrap十四

 

   

poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。如果对课程感兴趣,请大家咨询qq:908821478。

PressKeyCode

package io.appium.android.bootstrap.handler;

 

import com.android.uiautomator.core.UiDevice;

import io.appium.android.bootstrap.AndroidCommand;

import io.appium.android.bootstrap.AndroidCommandResult;

import io.appium.android.bootstrap.CommandHandler;

import org.json.JSONException;

import org.json.JSONObject;

 

import java.util.Hashtable;

 

/**

 * This handler is used to PressKeyCode.

 *

 */

public class PressKeyCode extends CommandHandler {

  public Integer keyCode;

  public Integer metaState;

 

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    try {

      final Hashtable<String, Object> params = command.params();

      Object kc = params.get("keycode");

      if (kc instanceof Integer) {

        keyCode = (Integer) kc;

      } else if (kc instanceof String) {

        keyCode = Integer.parseInt((String) kc);

      } else {

        throw new IllegalArgumentException("Keycode of type " + kc.getClass() + "not supported.");

      }

 

      if (params.get("metastate") != JSONObject.NULL) {

        metaState = (Integer) params.get("metastate");

        UiDevice.getInstance().pressKeyCode(keyCode, metaState);

      } else {

        UiDevice.getInstance().pressKeyCode(keyCode);

      }

 

      return getSuccessResult(true);

    } catch (final Exception e) {

      return getErrorResult(e.getMessage());

    }

  }

}

有的时候手机键盘的一些键需要按,但是又没有像pressBack这种方法供我们直接调用,这个时候我们就需要发送键盘的keycode来模拟这些键被点击。所以PressKeyCode就是封装这类事件的,通过上面的代码可以看出,发送keycode分2类事件,每一类调用的方法不一样

  • 单点键:pressKeyCode(keyCode,metaState)
  • 组合键:  pressKeyCode(keyCode,metaState)

LongPressKeyCode

package io.appium.android.bootstrap.handler;

 

import android.os.SystemClock;

import android.view.InputDevice;

import android.view.InputEvent;

import android.view.KeyCharacterMap;

import android.view.KeyEvent;

import com.android.uiautomator.common.ReflectionUtils;

import io.appium.android.bootstrap.AndroidCommand;

import io.appium.android.bootstrap.AndroidCommandResult;

import io.appium.android.bootstrap.CommandHandler;

import org.json.JSONException;

import org.json.JSONObject;

 

import java.lang.reflect.Method;

import java.util.Hashtable;

 

/**

 * This handler is used to LongPressKeyCode.

 *

 */

public class LongPressKeyCode extends CommandHandler {

  public Integer keyCode;

 

  public Integer metaState;

 

  /*

   * @param command The {@link AndroidCommand} used for this handler.

   *

   * @return {@link AndroidCommandResult}

   *

   * @throws JSONException

   *

   * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.

   * bootstrap.AndroidCommand)

   */

  @Override

  public AndroidCommandResult execute(final AndroidCommand command)

      throws JSONException {

    try {

      final ReflectionUtils utils = new ReflectionUtils();

      final Method injectEventSync = utils.getControllerMethod("injectEventSync",

          InputEvent.class);

      final Hashtable<String, Object> params = command.params();

      keyCode = (Integer) params.get("keycode");

      metaState = params.get("metastate") != JSONObject.NULL ? (Integer) params

          .get("metastate") : 0;

      final long eventTime = SystemClock.uptimeMillis();

      // Send an initial down event

      final KeyEvent downEvent = new KeyEvent(eventTime, eventTime,

          KeyEvent.ACTION_DOWN, keyCode, 0, metaState,

          KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);

      if ((Boolean) injectEventSync.invoke(utils.getController(), downEvent)) {

        // Send a repeat event. This will cause the FLAG_LONG_PRESS to be set.

        final KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(downEvent,

            eventTime, 1);

        injectEventSync.invoke(utils.getController(), repeatEvent);

        // Finally, send the up event

        final KeyEvent upEvent = new KeyEvent(eventTime, eventTime,

            KeyEvent.ACTION_UP, keyCode, 0, metaState,

            KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);

        injectEventSync.invoke(utils.getController(), upEvent);

      }

      return getSuccessResult(true);

    } catch (final Exception e) {

      return getErrorResult(e.getMessage());

    }

  }

}

长点击某个键盘键,和上面的单击是有区别的,因为没有直接的API可以调用,所以又要用到反射来做这件事,这次的反射呢调用的是InteractionController中的injectEventSync方法,首先会执行ACTION_DOWN,然后在一段时间里会重复执行这个down的动作,等事件到了以后,执行ACTION_UP这个动作松开键盘键。从而达到了我们到长按到要求。

posted @ 2015-11-10 15:45  北京茑萝信息  阅读(161)  评论(0编辑  收藏  举报