bootstrap之MultiPointerGesture

来源:互联网 发布:seo经验分享 编辑:程序博客网 时间:2024/05/02 04:27

MultiPointerGesture


package io.appium.android.bootstrap.handler;import android.view.MotionEvent.PointerCoords;import com.android.uiautomator.common.ReflectionUtils;import io.appium.android.bootstrap.*;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.lang.reflect.Method;import static io.appium.android.bootstrap.utils.API.API_18;public class MultiPointerGesture extends CommandHandler {  private double computeLongestTime(final JSONArray actions)      throws JSONException {    double max = 0.0;    for (int i = 0; i < actions.length(); i++) {      final JSONArray gestures = actions.getJSONArray(i);      final double endTime = gestures.getJSONObject(gestures.length() - 1)          .getDouble("time");      if (endTime > max) {        max = endTime;      }    }    return max;  }  private PointerCoords createPointerCoords(final JSONObject obj)      throws JSONException {    final JSONObject o = obj.getJSONObject("touch");    final int x = o.getInt("x");    final int y = o.getInt("y");    final PointerCoords p = new PointerCoords();    p.size = 1;    p.pressure = 1;    p.x = x;    p.y = y;    return p;  }  @Override  public AndroidCommandResult execute(final AndroidCommand command)      throws JSONException {    try {      final PointerCoords[][] pcs = parsePointerCoords(command);      if (command.isElementCommand()) {        final AndroidElement el = command.getElement();        if (el.performMultiPointerGesture(pcs)) {          return getSuccessResult("OK");        } else {          return getErrorResult("Unable to perform multi pointer gesture");        }      } else {        if (API_18) {          final ReflectionUtils utils = new ReflectionUtils();          final Method pmpg = utils.getControllerMethod("performMultiPointerGesture",              PointerCoords[][].class);          final Boolean rt = (Boolean) pmpg.invoke(utils.getController(),              (Object) pcs);          if (rt) {            return getSuccessResult("OK");          } else {            return getErrorResult("Unable to perform multi pointer gesture");          }        } else {          Logger.error("Device does not support API < 18!");          return new AndroidCommandResult(WDStatus.UNKNOWN_ERROR,              "Cannot perform multi pointer gesture on device below API level 18");        }      }    } catch (final Exception e) {      Logger.debug("Exception: " + e);      e.printStackTrace();      return new AndroidCommandResult(WDStatus.UNKNOWN_ERROR, e.getMessage());    }  }  private PointerCoords[] gesturesToPointerCoords(final double maxTime,      final JSONArray gestures) throws JSONException {    // gestures, e.g.:    // [    // {"touch":{"y":529.5,"x":120},"time":0.2},    // {"touch":{"y":529.5,"x":130},"time":0.4},    // {"touch":{"y":454.5,"x":140},"time":0.6},    // {"touch":{"y":304.5,"x":150},"time":0.8}    // ]    // From the docs:    // "Steps are injected about 5 milliseconds apart, so 100 steps may take    // around 0.5 seconds to complete."    final int steps = (int) (maxTime * 200) + 2;    final PointerCoords[] pc = new PointerCoords[steps];    int i = 1;    JSONObject current = gestures.getJSONObject(0);    double currentTime = current.getDouble("time");    double runningTime = 0.0;    final int gesturesLength = gestures.length();    for (int j = 0; j < steps; j++) {      if (runningTime > currentTime && i < gesturesLength) {        current = gestures.getJSONObject(i++);        currentTime = current.getDouble("time");      }      pc[j] = createPointerCoords(current);      runningTime += 0.005;    }    return pc;  }  private PointerCoords[][] parsePointerCoords(final AndroidCommand command)      throws JSONException {    final JSONArray actions = (org.json.JSONArray) command.params().get(        "actions");    final double time = computeLongestTime(actions);    final PointerCoords[][] pcs = new PointerCoords[actions.length()][];    for (int i = 0; i < actions.length(); i++) {      final JSONArray gestures = actions.getJSONArray(i);      pcs[i] = gesturesToPointerCoords(time, gestures);    }    return pcs;  }}

多点触控根据你传递过来的参数决定,如果参数是一个控件元素,那么就要调用performMultiPointerGesture方法,如果参数是一系列的点,那么就要调用反射。那么具体来看看2个方法细节。


控件


performMultiPointerGesture


public boolean performMultiPointerGesture(PointerCoords[] ...touches) {    try {      if (API_18) {        // The compile-time SDK expects the wrong arguments, but the runtime        // version in the emulator is correct. So we cannot do:        //   `return el.performMultiPointerGesture(touches);`        // Instead we need to use Reflection to do it all at runtime.        Method method = this.el.getClass().getMethod("performMultiPointerGesture", PointerCoords[][].class);        Boolean rt = (Boolean)method.invoke(this.el, (Object)touches);        return rt;      } else {        Logger.error("Device does not support API < 18!");        return false;      }    } catch (final Exception e) {      Logger.error("Exception: " + e + " (" + e.getMessage() + ")");      return false;    }  }


UiObject中有直接可以调用的performMultiPointerGesture方法,为什么还要用反射呢。上面的方法里的注释是这样解释的:编译的时候sdk会认为参数是错误的,但是运行时却认为是正确的,所以只有在运行时调用才能保证正确性。反射调用的就是运行时的环境,所以它使用了反射调用了performMultiPointerGesture。



点组


在api18以上的版本中才有传点组的方法可调用,所以先判断sdk的版本。如果api在18以上,那么就要调用InteractionController..performMultiPointerGesture的方法来执行



0 0
原创粉丝点击