Appium源码分析(五)-drag

来源:互联网 发布:js 控制重新打开页面 编辑:程序博客网 时间:2024/05/20 17:08

首先我们来看下drag的源代码吧。

@Override  public AndroidCommandResult execute(final AndroidCommand command)      throws JSONException {    // DragArguments is created on each execute which prevents leaking state    // across executions.    final DragArguments dragArgs = new DragArguments(command);    if (command.isElementCommand()) {      return dragElement(dragArgs);    } else {      return drag(dragArgs);    }  }

首先先获取到DragArguments的一个实例化对象,主要是获取command命令中的参数:起始的元素,结束的元素,开始结束的坐标,以及步数。具体看代码

public DragArguments(final AndroidCommand command) throws JSONException {      final Hashtable<String, Object> params = command.params();      try {        if (params.get("elementId") != JSONObject.NULL) {          el = command.getElement();        }      } catch (final Exception e) {        el = null;      }      try {        if (params.get("destElId") != JSONObject.NULL) {          destEl = command.getDestElement();        }      } catch (final Exception e) {        destEl = null;      }      start = new Point(params.get("startX"), params.get("startY"));      end = new Point(params.get("endX"), params.get("endY"));      steps = (Integer) params.get("steps");    }

以上的代码比较好理解,这里就不做详细解释了,下来判断comman命令是否是针对于元素的操作。其实这里也可以通过是否存在有开始的元素以及结束的元素来判断是否是针对于元素的操作。

  • 如果是针对于元素的Drag

private AndroidCommandResult dragElement(final DragArguments dragArgs) {    Point absEndPos = new Point();    if (dragArgs.destEl == null) {      try {        //这里判断如果无destEl时,那么就需要计算结束坐标相对于设备的坐标位置。这里的计算方法与swipe的转换是一样的        absEndPos = PositionHelper.getDeviceAbsPos(dragArgs.end);      } catch (final InvalidCoordinatesException e) {        return getErrorResult(e.getMessage());      } catch (final UiObjectNotFoundException e) {        return getErrorResult(e.getMessage());      }       Logger.debug("Dragging the element with id " + dragArgs.el.getId()          + " to " + absEndPos.toString() + " with steps: "          + dragArgs.steps.toString());      try {        //调用UiAutomator中的drag方法,这里需要注意api要大于18,如果小于则拖拽不成功        final boolean rv = dragArgs.el.dragTo(absEndPos.x.intValue(),            absEndPos.y.intValue(), dragArgs.steps);        if (!rv) {          return getErrorResult("Drag did not complete successfully");        } else {          return getSuccessResult(rv);        }      } catch (final UiObjectNotFoundException e) {        return getErrorResult("Drag did not complete successfully"            + e.getMessage());      }    } else {        //如果destEl不为空时,则调用Uiautomator另一个方法 boolean dragTo(UiObject destObj, int steps)      Logger.debug("Dragging the element with id " + dragArgs.el.getId()          + " to destination element with id " + dragArgs.destEl.getId()          + " with steps: " + dragArgs.steps);      try {        final boolean rv = dragArgs.el.dragTo(dragArgs.destEl.getUiObject(),            dragArgs.steps);        if (!rv) {          return getErrorResult("Drag did not complete successfully");        } else {          return getSuccessResult(rv);        }      } catch (final UiObjectNotFoundException e) {        return getErrorResult("Drag did not complete successfully"            + e.getMessage());      }    }  }

以上是针对于元素的操作

  • 如果是针对非元素的Drag
private AndroidCommandResult drag(final DragArguments dragArgs) {    Point absStartPos = new Point();    Point absEndPos = new Point();    final UiDevice device = UiDevice.getInstance();    try {    //这里分别将起始以及结束的坐标转换成相应的设备的坐标      absStartPos = PositionHelper.getDeviceAbsPos(dragArgs.start);      absEndPos = PositionHelper.getDeviceAbsPos(dragArgs.end);    } catch (final InvalidCoordinatesException e) {      return getErrorResult(e.getMessage());    } catch (final UiObjectNotFoundException e) {        return getErrorResult(e.getMessage());      }     Logger.debug("Dragging from " + absStartPos.toString() + " to "        + absEndPos.toString() + " with steps: " + dragArgs.steps.toString());    //再来也是一样的调用Uiautomator的drag方法    final boolean rv = device.drag(absStartPos.x.intValue(),        absStartPos.y.intValue(), absEndPos.x.intValue(),        absEndPos.y.intValue(), dragArgs.steps);    if (!rv) {      return getErrorResult("Drag did not complete successfully");    }    return getSuccessResult(rv);  }

但是问题来了,appium的api中貌似只提供了一个方法

# convenience method added to Appium (NOT Selenium 3)  def drag_and_drop(self, origin_el, destination_el):      """Drag the origin element to the destination element      :Args:       - originEl - the element to drag       - destinationEl - the element to drag to      """      action = TouchAction(self)      action.long_press(origin_el).move_to(destination_el).release().perform()      return self

那如果我想要实现一个点到另外一个点的拖拽那怎么做呢。实际我们只要研究下appium-client的源码就能得出结果了,我们看下drag_and_drop的源代码

def drag_and_drop(self, origin_el, destination_el):    """Drag the origin element to the destination element    :Args:     - originEl - the element to drag     - destinationEl - the element to drag to    """    action = TouchAction(self)    action.long_press(origin_el).move_to(destination_el).release().perform()    return self

内容很简单,先长按移动到对应点在松开。原来drag实际上到最后还是变成action进行实现的,那么这样子就简单了,我们也可以去构造出一个drag针对于坐标的

action1 = touch_action.TouchAction(self.driver)action = touch_action.TouchAction(self.driver)action.long_press(x=0.5,y=0.5).move_to(x=1.0,y=1.0).release().perform()

这样子就实现了拖拽的方法了,我们来看看appium 的log吧。

这里写图片描述

这样子是不是就清晰了很多呢

0 0
原创粉丝点击