pc端传过来的json字串有几个fields:
  cmd:代表这个是什么命令类型,其实是AndroidCommandType的那两个值
  package io.appium.android.bootstrap;
  /**
  * Enumeration for all the command types.
  *
  */
  public enum AndroidCommandType {
  ACTION, SHUTDOWN
  }
  action: 具体命令
  params: 提供的参数,这里提供了一个elementId的键值对
  从上面的两条调试信息看来,其实没有明显的看到究竟使用的是哪个控件。其实这里不起眼的elementId是确定用的是哪个控件的,注意这个elementId并不是一个控件在界面上的资源id,它其实是Bootstrap维护的一个保存所有已经获取过的控件的哈希表的键值。如上一小节看到的,每一个AndroidElement都有两个重要的成员变量:
  UiObject el :uiautomator框架中代表了一个真实的窗口控件
  Sting id :  一个的自动增加的字串类型整数,pc端是通过它来在AndroidElementHash这个类中找到想要的控件的
  3. AndroidElement控件哈希表
  上一节我们说到appium pc端是通过id把WebElement和目标机器端的AndroidElement映射起来的,那么我们这一节来看下维护AndroidElement的这个哈希表是怎么实现的。
  首先,它拥有两个成员变量:
  private final Hashtable<String, AndroidElement> elements;
  private       Integer                           counter;
  elements :一个以AndroidElement 的id的字串类型为key,以AndroidElement的实例为value的的哈希表
  counter : 一个整型变量,有两个作用:其一是它代表了当前已经用到的控件的数目(其实也不完全是,你在脚本中对同一个控件调用两次findElement其实会产生两个不同id的AndroidElement控件),其二是它代表了一个新用到的控件的id,而这个id是上面的elements哈希表的键
  这个哈希表的键值都是从0开始的,请看它的构造函数:
  /**
  * Constructor
  */
  public AndroidElementsHash() {
  counter = 0;
  elements = new Hashtable<String, AndroidElement>();
  }
  而它在整个Bootstrap中是有且只有一个实例的,且看它的单例模式实现:
  public static AndroidElementsHash getInstance() {
  if (AndroidElementsHash.instance == null) {
  AndroidElementsHash.instance = new AndroidElementsHash();
  }
  return AndroidElementsHash.instance;
  }
  以下增加一个控件的方法addElement充分描述了为什么说counter是一个自增加的key,且是每个新发现的AndroidElement控件的id:
  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;
  }
  从Appium发过来的控件查找命令大方向上分两类:
  1. 直接基于Appium Driver来查找,这种情况下appium发过来的json命令是不包含控件哈希表的键值信息的
  WebElement addNote = driver.findElement(By.name("Add note"));
  2. 基于父控件查找:
  WebElement el = driver.findElement(By.className("android.widget.ListView")).findElement(By.name("Note1"));
  以上的脚本会先尝试找到Note1这个日记的父控件ListView,并把这个控件保存到控件哈希表,然后再根据父控件的哈希表键值以及子控件的选择子找到想要的Note1: