在android4.2.2中的setText(String text)与android4.3的方法,内部是有些不一样的。但是我们是要学就学最新的嘛,就研究一下4.3的。其实4.2.2的也差不多。
4.3的源码
public boolean setText(String text) throws UiObjectNotFoundException {
Tracer.trace(text);
clearTextField();
return getInteractionController().sendText(text);
}
里面的clearTextField()的源码如下:
----------------------------------------------------------------------------------------------
public void clearTextField() throws UiObjectNotFoundException {
Tracer.trace();
// 找需要点击的对象的NodeInfo
AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
if(node == null) {
throw new UiObjectNotFoundException(getSelector().toString());
}
Rect rect = getVisibleBounds(node);
// 长按聚焦
getInteractionController().longTapNoSync(rect.left + 20, rect.centerY());
UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
if(selectAll.waitForExists(50))
selectAll.click();
// wait for the selection
SystemClock.sleep(250);
// delete it
getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
}
从源码可以看出,他是先制造一个痕迹,然后再找到需要的节点,再得到他的坐标(x轴+20,y轴的中间值,xy坐标原点在屏幕的左上角),然后长按 (时间是系统设置的长按时间),之后 SystemClock.sleep(250),等待 全选 后,执行delete键,即删除。
----------------------------------------------------------------------------------------------------
之后执行sendText(),
public boolean sendText(String text) {
if (DEBUG) {
Log.d(LOG_TAG, "sendText (" + text + ")");
}
KeyEvent[] events = mKeyCharacterMap.getEvents(text.toCharArray());
if (events != null) {
long keyDelay = Configurator.getInstance().getKeyInjectionDelay();
for (KeyEvent event2 : events) {
// We have to change the time of an event before injecting it because
// all KeyEvents returned by KeyCharacterMap.getEvents() have the same
// time stamp and the system rejects too old events. Hence, it is
// possible for an event to become stale before it is injected if it
// takes too long to inject the preceding ones.
KeyEvent event = KeyEvent.changeTimeRepeat(event2,
SystemClock.uptimeMillis(), 0);
if (!injectEventSync(event)) {
return false;
}
SystemClock.sleep(keyDelay);
}
}
return true;
}
他是完全模仿按键动作的。这里会有一个keyInjectionDelay(),就是插入俩个字母之间的时间间隔。最终完成字母插入动作。
所以,这里真正的setText(),执行的真正动作是,得到节点信息,再而得到节点的坐标,通过descriptionContains("Select all"),来全选,若没有则不能全选,之后点击,等250ms,执行删除键,再执行真正的按键输入动作,输入显示出你预先设定的输入内容(注意,该方法的输入方式是调用键盘的,所以一般能完成英文的输入,中文指定字符的输入会比较麻烦)。