• bootstrap之Swipe


    Swipe


    我定义为滑动,但它字面的意思又不是,事件的形式类似于小时候拿着一块石头片,朝水面飞过去,假设你手法能够那么就是swipe走的路线,假设你手法不行,接触水面的时候就没再飞起来那就会被人嘲笑的。


    package io.appium.android.bootstrap.handler;
    
    import com.android.uiautomator.core.UiDevice;
    import com.android.uiautomator.core.UiObjectNotFoundException;
    import io.appium.android.bootstrap.*;
    import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;
    import io.appium.android.bootstrap.utils.Point;
    import org.json.JSONException;
    
    import java.util.Hashtable;
    
    /**
     * This handler is used to swipe.
     * 
     */
    public class Swipe extends CommandHandler {
    
      /*
       * @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 {
        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();
    
        if (command.isElementCommand()) {
          try {
            final AndroidElement el = command.getElement();
            absStartPos = el.getAbsolutePosition(start);
            absEndPos = el.getAbsolutePosition(end, false);
          } catch (final UiObjectNotFoundException e) {
            return getErrorResult(e.getMessage());
          } catch (final InvalidCoordinatesException e) {
            return getErrorResult(e.getMessage());
          } catch (final Exception e) { // handle NullPointerException
            return getErrorResult("Unknown error");
          }
        } else {
          try {
            absStartPos = getDeviceAbsPos(start);
            absEndPos = getDeviceAbsPos(end);
          } catch (final InvalidCoordinatesException e) {
            return getErrorResult(e.getMessage());
          }
        }
    
        Logger.debug("Swiping from " + absStartPos.toString() + " to "
            + absEndPos.toString() + " with steps: " + steps.toString());
        final boolean rv = device.swipe(absStartPos.x.intValue(),
            absStartPos.y.intValue(), absEndPos.x.intValue(),
            absEndPos.y.intValue(), steps);
        if (!rv) {
          return getErrorResult("The swipe did not complete successfully");
        }
        return getSuccessResult(rv);
      }
    }
    

    无论它怎样定义,先分析源代码最后再定义。


        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;
      }

    上面的一大段代码,看起来非常复杂,事实上非常easy,业务非常容易理解,处理这样的点的时候就须要推断非常多东西。上面的代码首先分析x坐标然后分析y坐标。x和y坐标的推断和处理时一样的,所以我仅仅讲一下x坐标。

    首先推断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.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中命令格式

    • 控件
    • 坐标

    坐标又分为相对坐标百分比和绝对坐标两种方法。















  • 相关阅读:
    安装Kali Linux虚拟机02
    前端入门之——知识补充 day11
    套接字编程知识回顾01
    关于js中 document.body.scrollTop 不能返回正确值的原因
    前端入门之——后台管理页面布局 学习 day10
    前端入门之——jquery day9
    pickle序列化与反序列化 + eval说明
    json序列化与反序列化
    项目中日志输出常用的设置
    logging模块基础3
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3869722.html
Copyright © 2020-2023  润新知