先分析源码:

final Hashtable<String, Object> params = command.params();
final Point start = new Point(params.get("startX"), params.get("startY"));
final Point end = new Point(params.get("endX"), params.get("endY"));
final Integer steps = (Integer) params.get("steps");
final UiDevice device = UiDevice.getInstance();

    Point absStartPos = new Point();
    Point absEndPos = new Point();

首先从命令里获取参数,后解析出3个变量:起始点start、终点end、步骤steps。然后获得设备对象,定义2个私有Point对象,以备后用。
然后分条件处理,处理控件还是处理坐标。

控件:

final AndroidElement el = command.getElement();
absStartPos = el.getAbsolutePosition(start);
absEndPos = el.getAbsolutePosition(end, false);

首先获取控件对象,再通过getAbsolutePosition传入不同的参数获得在该控件上点击的起始点和结束点。

public Point getAbsolutePosition(final Point point,

      final boolean boundsChecking) throws UiObjectNotFoundException,

      InvalidCoordinatesException {

    final Rect rect = el.getBounds();

    final Point pos = new Point();

    Logger.debug("Element bounds: " + rect.toShortString());

 

    if (point.x == 0) {

      pos.x = rect.width() * 0.5 + rect.left;

    } else if (point.x <= 1) {

      pos.x = rect.width() * point.x + rect.left;

    } else {

      pos.x = rect.left + point.x;

    }

    if (boundsChecking) {

      if (pos.x > rect.right || pos.x < rect.left) {

        throw new InvalidCoordinatesException("X coordinate ("

            + pos.x.toString() + " is outside of element rect: "

            + rect.toShortString());

      }

    }

 

    if (point.y == 0) {

      pos.y = rect.height() * 0.5 + rect.top;

    } else if (point.y <= 1) {

      pos.y = rect.height() * point.y + rect.top;

    } else {

      pos.y = rect.left + point.y;

    }

    if (boundsChecking) {

      if (pos.y > rect.bottom || pos.y < rect.top) {

        throw new InvalidCoordinatesException("Y coordinate ("

            + pos.y.toString() + " is outside of element rect: "

            + rect.toShortString());

      }

    }

 

    return pos;

  }

上面的代码首先分析x坐标然后分析y坐标。x和y坐标的判断和处理时一样的

首先判断x坐标是否为0,如果为0,定义初始点的x坐标为控件的中心点的横坐标。如果x的坐标小于1,说明坐标为相对坐标,用百分比来求值,此时就要与宽度做乘积运算得到具体值。如果上面2种情况都不符合,那就是具体坐标值,那就直接元素的x坐标值加上控件的边框左坐标值。
最后根据传入的boolean值来判断是否做一个超出边界的验证。如果超出边界就跑出异常。y坐标的获取方式类似。最后得到坐标值并返回,回到execute方法中。

 

坐标

absStartPos = getDeviceAbsPos(start);
absEndPos = getDeviceAbsPos(end);

通过调用getDeviceAbsPos()方法得到坐标值来初始化之前声明的私有Point对象.

protected static Point getDeviceAbsPos(final Point point)

      throws InvalidCoordinatesException {

    final UiDevice d = UiDevice.getInstance();

    final Point retPos = new Point(point); // copy inputed point

 

    final Double width = (double) d.getDisplayWidth();

    if (point.x < 1) {

      retPos.x = width * point.x;

    }

 

    if (retPos.x > width || retPos.x < 0) {

      throw new InvalidCoordinatesException("X coordinate ("

          + retPos.x.toString() + " is outside of screen width: "

          + width.toString());

    }

 

    final Double height = (double) d.getDisplayHeight();

    if (point.y < 1) {

      retPos.y = height * point.y;

    }

 

    if (retPos.y > height || retPos.y < 0) {

      throw new InvalidCoordinatesException("Y coordinate ("

          + retPos.y.toString() + " is outside of screen height: "

          + height.toString());

    }

 

    return retPos;

  }

类似于上面的方法,也是要先判断传过来的坐标值是否小于1,如果小于1,当作百分比来球坐标值。如果超出屏幕的范围抛出异常,最后返回坐标值回到execute方法。

final boolean rv = device.swipe(absStartPos.x.intValue(),
absStartPos.y.intValue(), absEndPos.x.intValue(),
absEndPos.y.intValue(), steps);

最后调用UiDevice.swipe方法来执行命令,判断是否执行成功。

总结
执行swipe命令有2中命令格式
a.控件
b.坐标
坐标又分为相对坐标百分比和绝对坐标两种方法。