青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

專職C++

不能停止的腳步

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

常用鏈接

留言簿(28)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

使用appium輸入中文,發(fā)現(xiàn)好慢!至少5秒以上,如果在這樣的情況下做測試,這就好悲劇了。 
從appium(1.6.3)代碼上來看,沒有什么問題,直接是通過boostrap的setText的方法。說是就下載了appium-bootstrap的代碼看,從這里開發(fā)找到的代碼,都是java的代碼,找到 io.appium.android.bootstrap.handler.SetText 
在new Clear().execute(command);時間長達5秒(打日志發(fā)現(xiàn)),不管文本框有沒有內(nèi)容,都會執(zhí)行
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * You may obtain a copy of the License at
 *
 *     
http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 
*/

package io.appium.android.bootstrap.handler;

import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import io.appium.android.bootstrap.*;
import io.appium.android.bootstrap.exceptions.ElementNotFoundException;
import io.appium.android.bootstrap.handler.Find;
import org.json.JSONException;

import java.util.Hashtable;

/**
 * This handler is used to set text in elements that support it.
 *
 
*/
public class SetText 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 {
    AndroidElement el = null;
    if (command.isElementCommand()) {
      el = command.getElement();
      Logger.debug("Using element passed in: " + el.getId());
    } else {
      try {
        AndroidElementsHash  elements = AndroidElementsHash.getInstance();
        el = elements.getElement(new UiSelector().focused(true), "");
        Logger.debug("Using currently-focused element: " + el.getId());
      } catch (ElementNotFoundException e) {
        Logger.debug("Error retrieving focused element: " + e);
        return getErrorResult("Unable to set text without a focused element.");
      }
    }
    try {
      final Hashtable<String, Object> params = command.params();
      boolean replace = Boolean.parseBoolean(params.get("replace").toString());
      String text = params.get("text").toString();
      boolean pressEnter = false;
      if (text.endsWith("\\n")) {
        pressEnter = true;
        text = text.replace("\\n", "");
        Logger.debug("Will press enter after setting text");
      }
      boolean unicodeKeyboard = false;
      if (params.get("unicodeKeyboard") != null) {
        unicodeKeyboard = Boolean.parseBoolean(params.get("unicodeKeyboard").toString());
      }
      String currText = el.getText();
      new Clear().execute(command); //不管有沒有,這里都會執(zhí)行
      if (!el.getText().isEmpty()) {
        // clear could have failed, or we could have a hint in the field
        
// we'll assume it is the latter
        Logger.debug("Text not cleared. Assuming remainder is hint text.");
        currText = "";
      }
      if (!replace) {
        text = currText + text;
      }
      final boolean result = el.setText(text, unicodeKeyboard);
      if (!result) {
        return getErrorResult("el.setText() failed!");
      }
      if (pressEnter) {
        final UiDevice d = UiDevice.getInstance();
        d.pressEnter();
      }
      return getSuccessResult(result);
    } catch (final UiObjectNotFoundException e) {
      return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,
          e.getMessage());
    } catch (final Exception e) { // handle NullPointerException
      return getErrorResult("Unknown error");
    }
  }
}
然后,我們再看Clear的代碼

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * You may obtain a copy of the License at
 *
 *     
http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 
*/

package io.appium.android.bootstrap.handler;

import android.graphics.Rect;
import android.os.SystemClock;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import io.appium.android.bootstrap.AndroidCommand;
import io.appium.android.bootstrap.AndroidCommandResult;
import io.appium.android.bootstrap.AndroidElement;
import io.appium.android.bootstrap.CommandHandler;
import io.appium.android.bootstrap.Logger;
import io.appium.android.bootstrap.WDStatus;
import io.appium.uiautomator.core.InteractionController;
import io.appium.uiautomator.core.UiAutomatorBridge;
import org.json.JSONException;

import java.lang.reflect.InvocationTargetException;

/**
 * This handler is used to clear elements in the Android UI.
 *
 * Based on the element Id, clear that element.
 *
 * UiAutomator method clearText is flaky hence overriding it with custom implementation.
 
*/
public class Clear extends CommandHandler {

  /*
   * Trying to select entire text with correctLongClick and increasing time intervals.
   * Checking if element still has text in them and and if true falling back on UiAutomator clearText
   *
   * @param command The {@link AndroidCommand}
   *
   * @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 {
    if (command.isElementCommand()) {
      try {
        final AndroidElement el = command.getElement();

        // first, try to do native clearing
        Logger.debug("Attempting to clear using UiObject.clearText().");
        el.clearText();  //無條件都會執(zhí)行這塊。然后再分析clearText
        if (el.getText().isEmpty()) {
          return getSuccessResult(true);
        }

        // see if there is hint text
        if (hasHintText(el)) {
          Logger.debug("Text remains after clearing, "
              + "but it appears to be hint text.");
          return getSuccessResult(true);
        }

        // next try to select everything and delete
        Logger.debug("Clearing text not successful. Attempting to clear " +
                "by selecting all and deleting.");
        if (selectAndDelete(el)) {
          return getSuccessResult(true);
        }

        // see if there is hint text
        if (hasHintText(el)) {
          Logger.debug("Text remains after clearing, "
              + "but it appears to be hint text.");
          return getSuccessResult(true);
        }

        // finally try to send delete keys
        Logger.debug("Clearing text not successful. Attempting to clear " +
                "by sending delete keys.");
        if (sendDeleteKeys(el)) {
          return getSuccessResult(true);
        }

        if (!el.getText().isEmpty()) {
          // either there was a failure, or there is hint text
          if (hasHintText(el)) {
            Logger.debug("Text remains after clearing, " +
                    "but it appears to be hint text.");
            return getSuccessResult(true);
          } else if (!el.getText().isEmpty()) {
            Logger.debug("Exhausted all means to clear text but '" +
                    el.getText() + "' remains.");
            return getErrorResult("Clear text not successful.");
          }
        }
        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 clearing text");
      }
    }
    return getErrorResult("Unknown error");
  }

  private boolean selectAndDelete(AndroidElement el)
      throws UiObjectNotFoundException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException {
    Rect rect = el.getVisibleBounds();
    // Trying to select entire text.
    TouchLongClick.correctLongClick(rect.left + 20, rect.centerY(), 2000);
    UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
    if (selectAll.waitForExists(2000)) {
      selectAll.click();
    }
    // wait for the selection
    SystemClock.sleep(500);
    // delete it
    UiAutomatorBridge.getInstance().getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);

    return el.getText().isEmpty();
  }

  private boolean sendDeleteKeys(AndroidElement el)
      throws UiObjectNotFoundException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException {
    String tempTextHolder = "";

    // Preventing infinite while loop.
    while (!el.getText().isEmpty() && !tempTextHolder.equalsIgnoreCase(el.getText())) {
      // Trying send delete keys after clicking in text box.
      el.click();
      // Sending delete keys asynchronously, both forward and backward
      for (int key : new int[] { KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_FORWARD_DEL }) {
        tempTextHolder = el.getText();
        final int length = tempTextHolder.length();
        final long eventTime = SystemClock.uptimeMillis();
        KeyEvent deleteEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
                key, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
                InputDevice.SOURCE_KEYBOARD);
        for (int count = 0; count < length; count++) {
          UiAutomatorBridge.getInstance().injectInputEvent(deleteEvent, false);
        }
      }
    }

    return el.getText().isEmpty();
  }

  private boolean hasHintText(AndroidElement el)
      throws UiObjectNotFoundException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException {
    // to test if the remaining text is hint text, try sending a single
    
// delete key and testing if there is any change.
    
// ignore the off-chance that the delete silently fails and we get a false
    
// positive.
    String currText = el.getText();

    try {
      if (!el.getBoolAttribute("focused")) {
        Logger.debug("Could not check for hint text because the element is not focused!");
        return false;
      }
    } catch (final Exception e) {
      Logger.debug("Could not check for hint text: " + e.getMessage());
      return false;
    }

    InteractionController interactionController = UiAutomatorBridge.getInstance().getInteractionController();
    interactionController.sendKey(KeyEvent.KEYCODE_DEL, 0);
    interactionController.sendKey(KeyEvent.KEYCODE_FORWARD_DEL, 0);

    return currText.equals(el.getText());
  }
}
再看看AndroidElement.clearText是什么樣的
  public void clearText() throws UiObjectNotFoundException {
    el.clearTextField();
  }
這個都就是com.android.uiautomator.core.UiObject.clearTextField 
于是找再找到uiautomator的代碼再來分析(這個代碼需要下載andriod sdk,在對應(yīng)android版本的目錄下,會有源碼,也有uiautomator的源代碼),我這里的路徑是: 
Android\sdk\sources\android-19\com\android\uiautomator\core 
在UiObject.java找到clearTextField實現(xiàn)
/**
     * Clears the existing text contents in an editable field.
     *
     * The {
@link UiSelector} of this object must reference a UI element that is editable.
     *
     * When you call this method, the method first sets focus at the start edge of the field.
     * The method then simulates a long-press to select the existing text, and deletes the
     * selected text.
     *
     * If a "Select-All" option is displayed, the method will automatically attempt to use it
     * to ensure full text selection.
     *
     * Note that it is possible that not all the text in the field is selected; for example,
     * if the text contains separators such as spaces, slashes, at symbol etc.
     * Also, not all editable fields support the long-press functionality.
     *
     * 
@throws UiObjectNotFoundException
     * 
@since API Level 16
     
*/
    public void clearTextField() throws UiObjectNotFoundException {
        Tracer.trace();
        // long click left + center
        AccessibilityNodeInfo node = findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());
        if(node == null) {
            throw new UiObjectNotFoundException(getSelector().toString());
        }
        Rect rect = getVisibleBounds(node);
        getInteractionController().longTapNoSync(rect.left + 20, rect.centerY()); //長按
        
// check if the edit menu is open
        UiObject selectAll = new UiObject(new UiSelector().descriptionContains("Select all"));
        if(selectAll.waitForExists(50))
            selectAll.click();
        // wait for the selection
        SystemClock.sleep(250); //這里等250ms
        
// delete it
        getInteractionController().sendKey(KeyEvent.KEYCODE_DEL, 0);
    }
相信大家,可以找到慢的原因了。這里做一次長按,然再再做全選,然后再sleep(250),還有一個selectAll.waitForExists(50), 這些都是耗費時間的。
再找一下UiObject.java中setText的實現(xiàn)

    public boolean setText(String text) throws UiObjectNotFoundException {
        Tracer.trace(text);
        clearTextField();
        return getInteractionController().sendText(text);
    }
發(fā)現(xiàn)這里又調(diào)用了一次clearTextField,這樣算來,設(shè)一次文本,都會清理兩次文本,于是,這時間就長了。 
優(yōu)化:只需要將io.appium.android.bootstrap.handler.SetText中的new Clear().execute(command)去掉就可以了。

posted on 2017-05-27 17:35 冬瓜 閱讀(1889) 評論(0)  編輯 收藏 引用 所屬分類: 原創(chuàng)appium
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99精品国产在热久久下载| 欧美在线播放一区二区| 亚洲黄色三级| 欧美主播一区二区三区| 国产精品久久久久久久电影| 亚洲精品极品| 亚洲国产欧美日韩精品| 你懂的成人av| 亚洲三级电影在线观看| 欧美国产1区2区| 美女露胸一区二区三区| 亚洲欧洲日产国产综合网| 欧美成人一区二区在线 | 欧美成人小视频| 亚洲视频免费| 欧美日韩亚洲一区二区三区四区| 亚洲人成在线播放| 欧美激情亚洲激情| 欧美成人第一页| 亚洲久久一区| 日韩午夜在线视频| 国产精品初高中精品久久| 亚洲综合视频网| 午夜一区二区三区不卡视频| 国产亚洲成人一区| 免费观看成人www动漫视频| 美女视频黄 久久| 99视频精品免费观看| 亚洲视频一区在线观看| 国产一区二三区| 99re热精品| 国产乱人伦精品一区二区| 久久精品免费| 美玉足脚交一区二区三区图片| 亚洲精品视频免费观看| 亚洲手机视频| 亚洲第一区中文99精品| 一本色道久久88精品综合| 国产日韩欧美不卡| 亚洲国产欧美一区二区三区同亚洲 | 亚洲免费视频中文字幕| 国产日韩一区二区三区在线| 狂野欧美一区| 欧美日韩一区二区在线观看视频| 欧美呦呦网站| 欧美高清在线观看| 久久久91精品国产| 欧美精品1区2区| 久久久久国产精品一区二区| 欧美精品日韩一区| 久久天堂精品| 国产精品久久久久久超碰| 欧美大成色www永久网站婷| 国产精品乱子乱xxxx| 亚洲第一福利社区| 国产日韩欧美一区| 99国产精品自拍| 91久久极品少妇xxxxⅹ软件| 亚洲欧美日韩国产综合精品二区| 亚洲日本欧美在线| 欧美在线精品免播放器视频| 午夜伦欧美伦电影理论片| 久热国产精品| 欧美在线欧美在线| 欧美日韩亚洲另类| 亚洲第一黄色| 在线观看欧美日韩国产| 性做久久久久久久久| 亚洲欧美电影院| 欧美精品尤物在线| 亚洲电影网站| 亚洲黄网站在线观看| 久久精品国产第一区二区三区| 亚洲欧美日韩国产| 欧美日韩一本到| 亚洲人成久久| 亚洲福利视频二区| 久久青草欧美一区二区三区| 久久国产精品免费一区| 国产精品久久久爽爽爽麻豆色哟哟| 亚洲精品一区二区三区99| 亚洲欧洲精品一区二区| 鲁大师成人一区二区三区| 免费日韩一区二区| 18成人免费观看视频| 久久久精品一区| 久久亚洲精品视频| 一区二区三区在线免费播放| 久久成人免费| 亚洲日本视频| 久久精品国产精品亚洲综合| 亚洲免费视频成人| 欧美视频在线观看免费| 9人人澡人人爽人人精品| 亚洲一区二区视频在线| 欧美视频二区| 亚洲无毛电影| 久久成人18免费网站| 国产一区二区三区奇米久涩| 欧美尤物巨大精品爽| 美国十次成人| 亚洲日本激情| 欧美日韩国产综合网 | 欧美一区二区日韩| 久久午夜国产精品| 亚洲国产日韩欧美综合久久| 欧美成人精品一区二区三区| 亚洲精品日韩在线| 午夜精品久久久久影视| 国产在线拍偷自揄拍精品| 美女91精品| 中文久久精品| 老司机精品视频一区二区三区| 亚洲激情视频在线| 欧美性jizz18性欧美| 久久激情婷婷| 亚洲精品国产精品乱码不99 | 欧美在线视频一区| 亚洲福利视频免费观看| 亚洲婷婷综合久久一本伊一区| 国产精品v欧美精品∨日韩| 欧美一级艳片视频免费观看| 欧美成人自拍| 亚洲午夜在线| 国产一区二区三区免费观看| 欧美福利在线观看| 午夜精品99久久免费| 欧美韩国日本一区| 欧美一级片一区| 亚洲精品日本| 国模精品一区二区三区| 欧美精品在线视频观看| 亚洲欧美日韩一区二区三区在线| 欧美黑人在线播放| 欧美一区二区三区视频在线观看 | 亚洲激情自拍| 欧美中文字幕久久| 一级日韩一区在线观看| 精品动漫一区| 国产精品女人久久久久久| 欧美成人一区二区在线 | 亚洲欧洲精品一区二区精品久久久| 国产精品久久久久久久久久妞妞| 老司机免费视频一区二区| 亚洲欧美中文在线视频| 亚洲国产一区二区视频| 久久一区视频| 欧美中文字幕在线观看| 亚洲图片激情小说| 91久久嫩草影院一区二区| 国产亚洲a∨片在线观看| 国产精品久久综合| 欧美视频二区36p| 欧美日韩精品是欧美日韩精品| 久久久久一区二区三区| 午夜在线精品| 欧美刺激性大交免费视频| 欧美在线观看一区二区| 亚洲国产精品一区二区第四页av | 久久精品中文字幕一区二区三区| 99精品视频免费观看视频| 亚洲大黄网站| 精品51国产黑色丝袜高跟鞋| 国产欧美日韩亚洲| 国产精品多人| 国产精品狠色婷| 国产精品久久久久秋霞鲁丝| 欧美日韩精品伦理作品在线免费观看| 久久亚洲春色中文字幕| 久久精品国产综合精品| 久久精品国产亚洲一区二区| 欧美一区二区三区免费观看| 亚洲永久精品大片| 午夜免费日韩视频| 欧美一区2区视频在线观看| 性欧美长视频| 久久精品免费播放| 久久嫩草精品久久久久| 美女国产一区| 欧美日韩精品高清| 国产精品久久久久久一区二区三区 | 欧美日韩一区二区免费在线观看| 欧美精品激情在线观看| 欧美日韩国产丝袜另类| 欧美三级日韩三级国产三级| 国产精品theporn| 国产精品入口日韩视频大尺度| 国产精品人成在线观看免费| 国产乱码精品一区二区三区忘忧草| 国产精品永久免费视频| 国产一区二区三区在线观看免费视频 | 国产精品看片资源| 国产一区自拍视频| 亚洲第一色中文字幕| 一本一本大道香蕉久在线精品| 亚洲影院色在线观看免费| 欧美一区二区三区四区在线观看地址| 久久av一区二区| 欧美阿v一级看视频| 亚洲精品视频一区|