二、Click
1.Bootstrap的Click类
Click类就一个方法execute()方法
public AndroidCommandResult execute(final AndroidCommand command)
throws JSONException {
if (command.isElementCommand()) {
try {
final AndroidElement el = command.getElement();
el.click();
return getSuccessResult(true);
} catch (final UiObjectNotFoundException e) {
return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,
e.getMessage());
} catch (final Exception e) { // handle NullPointerException
return getErrorResult("Unknown error");
}
} else {
final Hashtable<String, Object> params = command.params();
Point coords = new Point(Double.parseDouble(params.get("x").toString()),
Double.parseDouble(params.get("y").toString()) );try {
coords = PositionHelper.getDeviceAbsPos(coords);
} catch (final UiObjectNotFoundException e) {
return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,
e.getMessage());
} catch (final InvalidCoordinatesException e) {
return new AndroidCommandResult(WDStatus.INVALID_ELEMENT_COORDINATES,
e.getMessage());
}final boolean res = UiDevice.getInstance().click(coords.x.intValue(), coords.y.intValue());
return getSuccessResult(res);
}
}
首先调用了AndroidCommand的isElementCommand,这个方法在之前也说过,这里再次用到。
2.Bootstrap的AndroidCommand类
isElementCommand方法代码如下
public boolean isElementCommand() {
if (cmdType == AndroidCommandType.ACTION) {
try {
return json.getString("action").startsWith("element:");
} catch (final JSONException e) {
return false;
}
}
return false;
}
很简单,action的值如果是以element:开始则返回true,否则返回false
3.回到Click类
可以打开Appium日志查看click点击操作中从客户端得到的数据action字段以element:开头,所以返回true,进入if语句块。
进入if语句块调用了AndroidCommand的getElement()方法
4.继续看Bootstrap的AndroidCommand类
主要用到的方法代码如下,其中的一些代码以省略号......表示就不列出来了
public class AndroidCommand {
JSONObject json;
AndroidCommandType cmdType;public AndroidCommand(final String jsonStr) throws JSONException,
CommandTypeException {
json = new JSONObject(jsonStr);
setType(json.getString("cmd"));
}......
public AndroidElement getElement() throws JSONException {
String elId = (String) params().get("elementId");
return AndroidElementsHash.getInstance().getElement(elId);
}
......
public Hashtable<String, Object> params() throws JSONException {
final JSONObject paramsObj = json.getJSONObject("params");
final Hashtable<String, Object> newParams = new Hashtable<String, Object>();
final Iterator<?> keys = paramsObj.keys();while (keys.hasNext()) {
final String param = (String) keys.next();
newParams.put(param, paramsObj.get(param));
}
return newParams;
}
}
先看看getElement()方法首先调用了params()方法得到Hashtable并取出elementId的值;可以回到上面Appium截图中看看在action字段后面的params字段,Hashtable就是存放了params字段值的内容。回到getElement()方法,最后调用了AndroidElementsHash的getElement(elId)方法
5.Bootstrap的AndroidElementsHash类
public class AndroidElementsHash {
private static final Pattern endsWithInstancePattern = Pattern.compile(".*INSTANCE=\\d+]$");
public static AndroidElementsHash getInstance() {
if (AndroidElementsHash.instance == null) {
AndroidElementsHash.instance = new AndroidElementsHash();
}
return AndroidElementsHash.instance;
}private final Hashtable<String, AndroidElement> elements;
private Integer counter;private static AndroidElementsHash instance;
public AndroidElementsHash() {
counter = 0;
elements = new Hashtable<String, AndroidElement>();
}
public AndroidElement addElement(final UiObject element) {
counter++;
final String key = counter.toString();
final AndroidElement el = new AndroidElement(key, element);
elements.put(key, el);
return el;
}
public AndroidElement getElement(final String key) {
return elements.get(key);
}}
在上篇说Find中通过AndroidElementsHash的addElement方法把元素加入到了Hashtable中,现在调用了另外一个getElement()方法从中取出得到元素返回
6.回到Click类
得到元素后,执行了AndroidElement的click()方法,实际上就是UiObject的click()方法,这样就完成了Appium操作转换成UiAutomator操作的转换。
在Click类中else语句块就是action字段的值不是以element:开头的情况下则是通过坐标点击操作,如下图做了一个坐标的点击操作Appium日志内容如下
通过取出x,y的值,最后通过UiDevice对象完成了click点击操作,就不细说了,通过坐标定位是不建议使用的,它会因手机分辨率、尺寸大小不同,元素的坐标位置也会不同,只有在所有定位都无效的情况下,再考虑使用。