﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-专职C++-随笔分类-appium</title><link>http://www.cppblog.com/zdhsoft/category/21247.html</link><description>不能停止的脚步</description><language>zh-cn</language><lastBuildDate>Sun, 28 May 2017 09:33:27 GMT</lastBuildDate><pubDate>Sun, 28 May 2017 09:33:27 GMT</pubDate><ttl>60</ttl><item><title>Appium输入慢的原因分析</title><link>http://www.cppblog.com/zdhsoft/archive/2017/05/27/214960.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Sat, 27 May 2017 09:35:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/05/27/214960.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214960.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/05/27/214960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214960.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214960.html</trackback:ping><description><![CDATA[<div id="wmd-preview-section-2"  preview-content"="" style="box-sizing: border-box; color: #3f3f3f; font-family: &quot;microsoft yahei&quot;; font-size: 15px; text-align: justify; background-color: #f6f6f6; outline: none !important;"><p style="box-sizing: border-box; outline: none !important; margin: 0px 0px 1.1em;"></p></div><div>使用appium输入中文，发现好慢！至少5秒以上，如果在这样的情况下做测试，这就好悲剧了。&nbsp;</div><div>从appium（1.6.3)代码上来看，没有什么问题，直接是通过boostrap的setText的方法。说是就下载了appium-bootstrap的代码看，从这里开发找到的代码，都是java的代码，找到 io.appium.android.bootstrap.handler.SetText&nbsp;</div><div>在new Clear().execute(command);时间长达5秒（打日志发现），不管文本框有没有内容，都会执行</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Licensed&nbsp;under&nbsp;the&nbsp;Apache&nbsp;License,&nbsp;Version&nbsp;2.0&nbsp;(the&nbsp;"License");<br />&nbsp;*&nbsp;you&nbsp;may&nbsp;not&nbsp;use&nbsp;this&nbsp;file&nbsp;except&nbsp;in&nbsp;compliance&nbsp;with&nbsp;the&nbsp;License.<br />&nbsp;*&nbsp;See&nbsp;the&nbsp;NOTICE&nbsp;file&nbsp;distributed&nbsp;with&nbsp;this&nbsp;work&nbsp;for&nbsp;additional<br />&nbsp;*&nbsp;information&nbsp;regarding&nbsp;copyright&nbsp;ownership.<br />&nbsp;*&nbsp;You&nbsp;may&nbsp;obtain&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;License&nbsp;at<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; text-decoration-line: underline;">http://www.apache.org/licenses/LICENSE-2.0</span><span style="color: #008000; "><br />&nbsp;*<br />&nbsp;*&nbsp;Unless&nbsp;required&nbsp;by&nbsp;applicable&nbsp;law&nbsp;or&nbsp;agreed&nbsp;to&nbsp;in&nbsp;writing,&nbsp;software<br />&nbsp;*&nbsp;distributed&nbsp;under&nbsp;the&nbsp;License&nbsp;is&nbsp;distributed&nbsp;on&nbsp;an&nbsp;"AS&nbsp;IS"&nbsp;BASIS,<br />&nbsp;*&nbsp;WITHOUT&nbsp;WARRANTIES&nbsp;OR&nbsp;CONDITIONS&nbsp;OF&nbsp;ANY&nbsp;KIND,&nbsp;either&nbsp;express&nbsp;or&nbsp;implied.<br />&nbsp;*&nbsp;See&nbsp;the&nbsp;License&nbsp;for&nbsp;the&nbsp;specific&nbsp;language&nbsp;governing&nbsp;permissions&nbsp;and<br />&nbsp;*&nbsp;limitations&nbsp;under&nbsp;the&nbsp;License.<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><br /><span style="color: #0000FF; ">package</span>&nbsp;io.appium.android.bootstrap.handler;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiDevice;<br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiObjectNotFoundException;<br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiSelector;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.*;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.exceptions.ElementNotFoundException;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.handler.Find;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.json.JSONException;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;java.util.Hashtable;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;This&nbsp;handler&nbsp;is&nbsp;used&nbsp;to&nbsp;set&nbsp;text&nbsp;in&nbsp;elements&nbsp;that&nbsp;support&nbsp;it.<br />&nbsp;*<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;SetText&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;CommandHandler&nbsp;{<br /><br />&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;command&nbsp;The&nbsp;{@link&nbsp;AndroidCommand}&nbsp;used&nbsp;for&nbsp;this&nbsp;handler.<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;{@link&nbsp;AndroidCommandResult}<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;JSONException<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.<br />&nbsp;&nbsp;&nbsp;*&nbsp;bootstrap.AndroidCommand)<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;AndroidCommandResult&nbsp;execute(<span style="color: #0000FF; ">final</span>&nbsp;AndroidCommand&nbsp;command)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;JSONException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;AndroidElement&nbsp;el&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(command.isElementCommand())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el&nbsp;=&nbsp;command.getElement();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Using&nbsp;element&nbsp;passed&nbsp;in:&nbsp;"&nbsp;+&nbsp;el.getId());<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AndroidElementsHash&nbsp;&nbsp;elements&nbsp;=&nbsp;AndroidElementsHash.getInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el&nbsp;=&nbsp;elements.getElement(<span style="color: #0000FF; ">new</span>&nbsp;UiSelector().focused(<span style="color: #0000FF; ">true</span>),&nbsp;"");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Using&nbsp;currently-focused&nbsp;element:&nbsp;"&nbsp;+&nbsp;el.getId());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(ElementNotFoundException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Error&nbsp;retrieving&nbsp;focused&nbsp;element:&nbsp;"&nbsp;+&nbsp;e);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("Unable&nbsp;to&nbsp;set&nbsp;text&nbsp;without&nbsp;a&nbsp;focused&nbsp;element.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Hashtable&lt;String,&nbsp;Object&gt;&nbsp;params&nbsp;=&nbsp;command.params();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;replace&nbsp;=&nbsp;Boolean.parseBoolean(params.get("replace").toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;text&nbsp;=&nbsp;params.get("text").toString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;pressEnter&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(text.endsWith("\\n"))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pressEnter&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;=&nbsp;text.replace("\\n",&nbsp;"");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Will&nbsp;press&nbsp;enter&nbsp;after&nbsp;setting&nbsp;text");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;unicodeKeyboard&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(params.get("unicodeKeyboard")&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unicodeKeyboard&nbsp;=&nbsp;Boolean.parseBoolean(params.get("unicodeKeyboard").toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;currText&nbsp;=&nbsp;el.getText();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Clear().execute(command);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">不管有没有，这里都会执行</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!el.getText().isEmpty())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;clear&nbsp;could&nbsp;have&nbsp;failed,&nbsp;or&nbsp;we&nbsp;could&nbsp;have&nbsp;a&nbsp;hint&nbsp;in&nbsp;the&nbsp;field<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;we'll&nbsp;assume&nbsp;it&nbsp;is&nbsp;the&nbsp;latter</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Text&nbsp;not&nbsp;cleared.&nbsp;Assuming&nbsp;remainder&nbsp;is&nbsp;hint&nbsp;text.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currText&nbsp;=&nbsp;"";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!replace)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text&nbsp;=&nbsp;currText&nbsp;+&nbsp;text;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;result&nbsp;=&nbsp;el.setText(text,&nbsp;unicodeKeyboard);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!result)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("el.setText()&nbsp;failed!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(pressEnter)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;UiDevice&nbsp;d&nbsp;=&nbsp;UiDevice.getInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d.pressEnter();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(result);<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">final</span>&nbsp;UiObjectNotFoundException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.getMessage());<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">final</span>&nbsp;Exception&nbsp;e)&nbsp;{&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;handle&nbsp;NullPointerException</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("Unknown&nbsp;error");<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}</div></div><div>然后，我们再看Clear的代码</div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br /><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Licensed&nbsp;under&nbsp;the&nbsp;Apache&nbsp;License,&nbsp;Version&nbsp;2.0&nbsp;(the&nbsp;"License");<br />&nbsp;*&nbsp;you&nbsp;may&nbsp;not&nbsp;use&nbsp;this&nbsp;file&nbsp;except&nbsp;in&nbsp;compliance&nbsp;with&nbsp;the&nbsp;License.<br />&nbsp;*&nbsp;See&nbsp;the&nbsp;NOTICE&nbsp;file&nbsp;distributed&nbsp;with&nbsp;this&nbsp;work&nbsp;for&nbsp;additional<br />&nbsp;*&nbsp;information&nbsp;regarding&nbsp;copyright&nbsp;ownership.<br />&nbsp;*&nbsp;You&nbsp;may&nbsp;obtain&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;License&nbsp;at<br />&nbsp;*<br />&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; text-decoration-line: underline;">http://www.apache.org/licenses/LICENSE-2.0</span><span style="color: #008000; "><br />&nbsp;*<br />&nbsp;*&nbsp;Unless&nbsp;required&nbsp;by&nbsp;applicable&nbsp;law&nbsp;or&nbsp;agreed&nbsp;to&nbsp;in&nbsp;writing,&nbsp;software<br />&nbsp;*&nbsp;distributed&nbsp;under&nbsp;the&nbsp;License&nbsp;is&nbsp;distributed&nbsp;on&nbsp;an&nbsp;"AS&nbsp;IS"&nbsp;BASIS,<br />&nbsp;*&nbsp;WITHOUT&nbsp;WARRANTIES&nbsp;OR&nbsp;CONDITIONS&nbsp;OF&nbsp;ANY&nbsp;KIND,&nbsp;either&nbsp;express&nbsp;or&nbsp;implied.<br />&nbsp;*&nbsp;See&nbsp;the&nbsp;License&nbsp;for&nbsp;the&nbsp;specific&nbsp;language&nbsp;governing&nbsp;permissions&nbsp;and<br />&nbsp;*&nbsp;limitations&nbsp;under&nbsp;the&nbsp;License.<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><br /><span style="color: #0000FF; ">package</span>&nbsp;io.appium.android.bootstrap.handler;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;android.graphics.Rect;<br /><span style="color: #0000FF; ">import</span>&nbsp;android.os.SystemClock;<br /><span style="color: #0000FF; ">import</span>&nbsp;android.view.InputDevice;<br /><span style="color: #0000FF; ">import</span>&nbsp;android.view.KeyCharacterMap;<br /><span style="color: #0000FF; ">import</span>&nbsp;android.view.KeyEvent;<br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiObject;<br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiObjectNotFoundException;<br /><span style="color: #0000FF; ">import</span>&nbsp;com.android.uiautomator.core.UiSelector;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.AndroidCommand;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.AndroidCommandResult;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.AndroidElement;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.CommandHandler;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.Logger;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.android.bootstrap.WDStatus;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.uiautomator.core.InteractionController;<br /><span style="color: #0000FF; ">import</span>&nbsp;io.appium.uiautomator.core.UiAutomatorBridge;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.json.JSONException;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;java.lang.reflect.InvocationTargetException;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;This&nbsp;handler&nbsp;is&nbsp;used&nbsp;to&nbsp;clear&nbsp;elements&nbsp;in&nbsp;the&nbsp;Android&nbsp;UI.<br />&nbsp;*<br />&nbsp;*&nbsp;Based&nbsp;on&nbsp;the&nbsp;element&nbsp;Id,&nbsp;clear&nbsp;that&nbsp;element.<br />&nbsp;*<br />&nbsp;*&nbsp;UiAutomator&nbsp;method&nbsp;clearText&nbsp;is&nbsp;flaky&nbsp;hence&nbsp;overriding&nbsp;it&nbsp;with&nbsp;custom&nbsp;implementation.<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Clear&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;CommandHandler&nbsp;{<br /><br />&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;*&nbsp;Trying&nbsp;to&nbsp;select&nbsp;entire&nbsp;text&nbsp;with&nbsp;correctLongClick&nbsp;and&nbsp;increasing&nbsp;time&nbsp;intervals.<br />&nbsp;&nbsp;&nbsp;*&nbsp;Checking&nbsp;if&nbsp;element&nbsp;still&nbsp;has&nbsp;text&nbsp;in&nbsp;them&nbsp;and&nbsp;and&nbsp;if&nbsp;true&nbsp;falling&nbsp;back&nbsp;on&nbsp;UiAutomator&nbsp;clearText<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;command&nbsp;The&nbsp;{@link&nbsp;AndroidCommand}<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;{@link&nbsp;AndroidCommandResult}<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;JSONException<br />&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.<br />&nbsp;&nbsp;&nbsp;*&nbsp;bootstrap.AndroidCommand)<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;AndroidCommandResult&nbsp;execute(<span style="color: #0000FF; ">final</span>&nbsp;AndroidCommand&nbsp;command)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;JSONException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(command.isElementCommand())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;AndroidElement&nbsp;el&nbsp;=&nbsp;command.getElement();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;first,&nbsp;try&nbsp;to&nbsp;do&nbsp;native&nbsp;clearing</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Attempting&nbsp;to&nbsp;clear&nbsp;using&nbsp;UiObject.clearText().");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.clearText();&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">无条件都会执行这块。然后再分析clearText</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(el.getText().isEmpty())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;see&nbsp;if&nbsp;there&nbsp;is&nbsp;hint&nbsp;text</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(hasHintText(el))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Text&nbsp;remains&nbsp;after&nbsp;clearing,&nbsp;"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;"but&nbsp;it&nbsp;appears&nbsp;to&nbsp;be&nbsp;hint&nbsp;text.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;next&nbsp;try&nbsp;to&nbsp;select&nbsp;everything&nbsp;and&nbsp;delete</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Clearing&nbsp;text&nbsp;not&nbsp;successful.&nbsp;Attempting&nbsp;to&nbsp;clear&nbsp;"&nbsp;+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"by&nbsp;selecting&nbsp;all&nbsp;and&nbsp;deleting.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(selectAndDelete(el))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;see&nbsp;if&nbsp;there&nbsp;is&nbsp;hint&nbsp;text</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(hasHintText(el))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Text&nbsp;remains&nbsp;after&nbsp;clearing,&nbsp;"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;"but&nbsp;it&nbsp;appears&nbsp;to&nbsp;be&nbsp;hint&nbsp;text.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;finally&nbsp;try&nbsp;to&nbsp;send&nbsp;delete&nbsp;keys</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Clearing&nbsp;text&nbsp;not&nbsp;successful.&nbsp;Attempting&nbsp;to&nbsp;clear&nbsp;"&nbsp;+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"by&nbsp;sending&nbsp;delete&nbsp;keys.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(sendDeleteKeys(el))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!el.getText().isEmpty())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;either&nbsp;there&nbsp;was&nbsp;a&nbsp;failure,&nbsp;or&nbsp;there&nbsp;is&nbsp;hint&nbsp;text</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(hasHintText(el))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Text&nbsp;remains&nbsp;after&nbsp;clearing,&nbsp;"&nbsp;+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"but&nbsp;it&nbsp;appears&nbsp;to&nbsp;be&nbsp;hint&nbsp;text.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!el.getText().isEmpty())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Exhausted&nbsp;all&nbsp;means&nbsp;to&nbsp;clear&nbsp;text&nbsp;but&nbsp;'"&nbsp;+<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.getText()&nbsp;+&nbsp;"'&nbsp;remains.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("Clear&nbsp;text&nbsp;not&nbsp;successful.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getSuccessResult(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">final</span>&nbsp;UiObjectNotFoundException&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.getMessage());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">final</span>&nbsp;Exception&nbsp;e)&nbsp;{&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;handle&nbsp;NullPointerException</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("Unknown&nbsp;error&nbsp;clearing&nbsp;text");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getErrorResult("Unknown&nbsp;error");<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;selectAndDelete(AndroidElement&nbsp;el)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException,&nbsp;IllegalAccessException,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InvocationTargetException,&nbsp;NoSuchMethodException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;Rect&nbsp;rect&nbsp;=&nbsp;el.getVisibleBounds();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Trying&nbsp;to&nbsp;select&nbsp;entire&nbsp;text.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;TouchLongClick.correctLongClick(rect.left&nbsp;+&nbsp;20,&nbsp;rect.centerY(),&nbsp;2000);<br />&nbsp;&nbsp;&nbsp;&nbsp;UiObject&nbsp;selectAll&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;UiObject(<span style="color: #0000FF; ">new</span>&nbsp;UiSelector().descriptionContains("Select&nbsp;all"));<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(selectAll.waitForExists(2000))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectAll.click();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;wait&nbsp;for&nbsp;the&nbsp;selection</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;SystemClock.sleep(500);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;delete&nbsp;it</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;UiAutomatorBridge.getInstance().getInteractionController().sendKey(KeyEvent.KEYCODE_DEL,&nbsp;0);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;el.getText().isEmpty();<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;sendDeleteKeys(AndroidElement&nbsp;el)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException,&nbsp;IllegalAccessException,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InvocationTargetException,&nbsp;NoSuchMethodException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;tempTextHolder&nbsp;=&nbsp;"";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Preventing&nbsp;infinite&nbsp;while&nbsp;loop.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(!el.getText().isEmpty()&nbsp;&amp;&amp;&nbsp;!tempTextHolder.equalsIgnoreCase(el.getText()))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Trying&nbsp;send&nbsp;delete&nbsp;keys&nbsp;after&nbsp;clicking&nbsp;in&nbsp;text&nbsp;box.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el.click();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Sending&nbsp;delete&nbsp;keys&nbsp;asynchronously,&nbsp;both&nbsp;forward&nbsp;and&nbsp;backward</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;key&nbsp;:&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>[]&nbsp;{&nbsp;KeyEvent.KEYCODE_DEL,&nbsp;KeyEvent.KEYCODE_FORWARD_DEL&nbsp;})&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempTextHolder&nbsp;=&nbsp;el.getText();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length&nbsp;=&nbsp;tempTextHolder.length();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;eventTime&nbsp;=&nbsp;SystemClock.uptimeMillis();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyEvent&nbsp;deleteEvent&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;KeyEvent(eventTime,&nbsp;eventTime,&nbsp;KeyEvent.ACTION_DOWN,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key,&nbsp;0,&nbsp;0,&nbsp;KeyCharacterMap.VIRTUAL_KEYBOARD,&nbsp;0,&nbsp;0,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputDevice.SOURCE_KEYBOARD);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;count&nbsp;=&nbsp;0;&nbsp;count&nbsp;&lt;&nbsp;length;&nbsp;count++)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UiAutomatorBridge.getInstance().injectInputEvent(deleteEvent,&nbsp;<span style="color: #0000FF; ">false</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;el.getText().isEmpty();<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasHintText(AndroidElement&nbsp;el)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException,&nbsp;IllegalAccessException,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InvocationTargetException,&nbsp;NoSuchMethodException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;to&nbsp;test&nbsp;if&nbsp;the&nbsp;remaining&nbsp;text&nbsp;is&nbsp;hint&nbsp;text,&nbsp;try&nbsp;sending&nbsp;a&nbsp;single<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;delete&nbsp;key&nbsp;and&nbsp;testing&nbsp;if&nbsp;there&nbsp;is&nbsp;any&nbsp;change.<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;ignore&nbsp;the&nbsp;off-chance&nbsp;that&nbsp;the&nbsp;delete&nbsp;silently&nbsp;fails&nbsp;and&nbsp;we&nbsp;get&nbsp;a&nbsp;false<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;positive.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;currText&nbsp;=&nbsp;el.getText();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(!el.getBoolAttribute("focused"))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Could&nbsp;not&nbsp;check&nbsp;for&nbsp;hint&nbsp;text&nbsp;because&nbsp;the&nbsp;element&nbsp;is&nbsp;not&nbsp;focused!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(<span style="color: #0000FF; ">final</span>&nbsp;Exception&nbsp;e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger.debug("Could&nbsp;not&nbsp;check&nbsp;for&nbsp;hint&nbsp;text:&nbsp;"&nbsp;+&nbsp;e.getMessage());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;InteractionController&nbsp;interactionController&nbsp;=&nbsp;UiAutomatorBridge.getInstance().getInteractionController();<br />&nbsp;&nbsp;&nbsp;&nbsp;interactionController.sendKey(KeyEvent.KEYCODE_DEL,&nbsp;0);<br />&nbsp;&nbsp;&nbsp;&nbsp;interactionController.sendKey(KeyEvent.KEYCODE_FORWARD_DEL,&nbsp;0);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;currText.equals(el.getText());<br />&nbsp;&nbsp;}<br />}</div></div><div>再看看AndroidElement.clearText是什么样的</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;clearText()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;el.clearTextField();<br />&nbsp;&nbsp;}</div></div><div>这个都就是com.android.uiautomator.core.UiObject.clearTextField&nbsp;</div><div>于是找再找到uiautomator的代码再来分析（这个代码需要下载andriod sdk,在对应android版本的目录下，会有源码，也有uiautomator的源代码),我这里的路径是：&nbsp;</div><div>Android\sdk\sources\android-19\com\android\uiautomator\core&nbsp;</div><div>在UiObject.java找到clearTextField实现</div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Clears&nbsp;the&nbsp;existing&nbsp;text&nbsp;contents&nbsp;in&nbsp;an&nbsp;editable&nbsp;field.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;{</span><span style="color: #808080; ">@link</span><span style="color: #008000; ">&nbsp;UiSelector}&nbsp;of&nbsp;this&nbsp;object&nbsp;must&nbsp;reference&nbsp;a&nbsp;UI&nbsp;element&nbsp;that&nbsp;is&nbsp;editable.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;When&nbsp;you&nbsp;call&nbsp;this&nbsp;method,&nbsp;the&nbsp;method&nbsp;first&nbsp;sets&nbsp;focus&nbsp;at&nbsp;the&nbsp;start&nbsp;edge&nbsp;of&nbsp;the&nbsp;field.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;method&nbsp;then&nbsp;simulates&nbsp;a&nbsp;long-press&nbsp;to&nbsp;select&nbsp;the&nbsp;existing&nbsp;text,&nbsp;and&nbsp;deletes&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;selected&nbsp;text.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;If&nbsp;a&nbsp;"Select-All"&nbsp;option&nbsp;is&nbsp;displayed,&nbsp;the&nbsp;method&nbsp;will&nbsp;automatically&nbsp;attempt&nbsp;to&nbsp;use&nbsp;it<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;to&nbsp;ensure&nbsp;full&nbsp;text&nbsp;selection.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Note&nbsp;that&nbsp;it&nbsp;is&nbsp;possible&nbsp;that&nbsp;not&nbsp;all&nbsp;the&nbsp;text&nbsp;in&nbsp;the&nbsp;field&nbsp;is&nbsp;selected;&nbsp;for&nbsp;example,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;if&nbsp;the&nbsp;text&nbsp;contains&nbsp;separators&nbsp;such&nbsp;as&nbsp;spaces,&nbsp;slashes,&nbsp;at&nbsp;symbol&nbsp;etc.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Also,&nbsp;not&nbsp;all&nbsp;editable&nbsp;fields&nbsp;support&nbsp;the&nbsp;long-press&nbsp;functionality.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@throws</span><span style="color: #008000; ">&nbsp;UiObjectNotFoundException<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;API&nbsp;Level&nbsp;16<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;clearTextField()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tracer.trace();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;long&nbsp;click&nbsp;left&nbsp;+&nbsp;center</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AccessibilityNodeInfo&nbsp;node&nbsp;=&nbsp;findAccessibilityNodeInfo(mConfig.getWaitForSelectorTimeout());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(node&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;UiObjectNotFoundException(getSelector().toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rect&nbsp;rect&nbsp;=&nbsp;getVisibleBounds(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInteractionController().longTapNoSync(rect.left&nbsp;+&nbsp;20,&nbsp;rect.centerY());&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">长按<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;check&nbsp;if&nbsp;the&nbsp;edit&nbsp;menu&nbsp;is&nbsp;open</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UiObject&nbsp;selectAll&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;UiObject(<span style="color: #0000FF; ">new</span>&nbsp;UiSelector().descriptionContains("Select&nbsp;all"));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(selectAll.waitForExists(50))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectAll.click();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;wait&nbsp;for&nbsp;the&nbsp;selection</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SystemClock.sleep(250);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">这里等250ms<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;delete&nbsp;it</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInteractionController().sendKey(KeyEvent.KEYCODE_DEL,&nbsp;0);<br />&nbsp;&nbsp;&nbsp;&nbsp;}</div></div><div>相信大家，可以找到慢的原因了。这里做一次长按，然再再做全选，然后再sleep(250)，还有一个selectAll.waitForExists(50)， 这些都是耗费时间的。</div><div></div><div>再找一下UiObject.java中setText的实现</div><div><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;setText(String&nbsp;text)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;UiObjectNotFoundException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tracer.trace(text);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clearTextField();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;getInteractionController().sendText(text);<br />&nbsp;&nbsp;&nbsp;&nbsp;}</div></div><div>发现这里又调用了一次clearTextField，这样算来，设一次文本，都会清理两次文本，于是，这时间就长了。&nbsp;</div><div>优化：只需要将io.appium.android.bootstrap.handler.SetText中的new Clear().execute(command)去掉就可以了。</div><div id="wmd-preview-section-7"  preview-content"="" style="box-sizing: border-box; color: #3f3f3f; font-family: &quot;microsoft yahei&quot;; font-size: 15px; text-align: justify; background-color: #f6f6f6; outline: none !important;"><p style="box-sizing: border-box; outline: none !important; margin: 0px 0px 1.1em;"></p></div><img src ="http://www.cppblog.com/zdhsoft/aggbug/214960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-05-27 17:35 <a href="http://www.cppblog.com/zdhsoft/archive/2017/05/27/214960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appium的一个内存泄露bug</title><link>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214695.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Thu, 23 Feb 2017 12:35:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214695.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214695.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214695.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214695.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 注:关于node-heapdump请看  使用node heapdump<br><br>基于appium源码 1.6.3 运行,发现运行一段时间后,会出现内存溢出.<br>用node-heapdump生成heap快照  发现多了很多字符串对象:内容如下&nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2017/02/23/214695.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-02-23 20:35 <a href="http://www.cppblog.com/zdhsoft/archive/2017/02/23/214695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用node heapdump</title><link>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214693.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Thu, 23 Feb 2017 06:28:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214693.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214693.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/02/23/214693.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214693.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214693.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在使用appium的过程中，发现有内存泄露，最后就process out of memory了，就挂了<br>网上用使用增加运行内存的方式(还是抗不住)，没办法，就只好找出内存泄露的地方了<br>对node.js很多文章，都是说用memwatch，结果发现，这个是一个死项目，有四年没有更新过了，在现有的环境下，是没有办法编译的。<br>然后又有一个memwatch-next，顾名思义，就是memwatch的下一个版本，结果是果然也可以编译，一些事件也支持，但是要headdump后要end后，就挂了。<br>国内，用百度，你一万年都别想解决问题，估计找成人不宜的东西，百度世界第一名，google也不比过百度。&nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2017/02/23/214693.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214693.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-02-23 14:28 <a href="http://www.cppblog.com/zdhsoft/archive/2017/02/23/214693.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appium的source返回的xml字符串处理的工具函数</title><link>http://www.cppblog.com/zdhsoft/archive/2017/02/20/214688.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Mon, 20 Feb 2017 06:31:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/02/20/214688.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214688.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/02/20/214688.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214688.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214688.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这里是基于node的xmldom上扩展的工具，在使用appium的时候，常常需要用source功能来分析当前上下文，所以扩展了若干函数，用于分析。这些代码是基于node 6.9.x&nbsp;JavaScript&nbsp;ES6语法实现。（关于如何在node使用ES6的语法，请参考我的前文：js笔记四:node 6.9.x for gulp完整配置过程）完成代码如下：xml_utils.jsCo...&nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2017/02/20/214688.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214688.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-02-20 14:31 <a href="http://www.cppblog.com/zdhsoft/archive/2017/02/20/214688.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appium的UiAutomator exited unexpectedly(1.6.3)</title><link>http://www.cppblog.com/zdhsoft/archive/2017/02/08/214663.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Wed, 08 Feb 2017 06:39:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/02/08/214663.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214663.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/02/08/214663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214663.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214663.html</trackback:ping><description><![CDATA[<span style="background-color: rgba(0, 0, 0, 0.0392157);"><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size: 11.9px;">今天用新手机，运行appium 1.6.3 测试，发现日志打印如下错误：</span></font><br /></span><div><span style="font-size: 11.9px;">[debug] [ADB] Creating ADB subprocess with args: ["-P",5037,"-s","xxxxxxxxxxx","shell","uiautomator","runtest","AppiumBootstrap.jar","-c","io.appium.android.bootstrap.Bootstrap","-e","pkg","com.tencent.mm","-e","disableAndroidWatchers",false,"-e","acceptSslCerts",false]</span></div><div><span style="font-size: 11.9px;">[UiAutomator] UiAutomator exited unexpectedly with code 0, signal null<br />仔细看日志发现</span><span style="color: #333333; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 11.9px;">，发现/data/local/tmp缺少</span><span style="color: #333333; font-size: 11.9px;">AppiumBootstrap.jar</span></div><div style="color: #333333; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 11.9px;"><span style="font-family: verdana, &quot;courier new&quot;; font-size: 11.9px;">然后在appium的node_module目录下面的</span><span style="font-size: 11.9px;">appium-android-bootstrap\bootstrap\bin找到</span><span style="font-family: verdana, &quot;courier new&quot;; font-size: 11.9px;">AppiumBootstrap.jar，然后复制到</span><span style="font-size: 11.9px;">/data/local/tmp就可以，然后再运行，测试OK<br /><br /></span><br /></div><img src ="http://www.cppblog.com/zdhsoft/aggbug/214663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-02-08 14:39 <a href="http://www.cppblog.com/zdhsoft/archive/2017/02/08/214663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appium的中文输入</title><link>http://www.cppblog.com/zdhsoft/archive/2017/01/06/214578.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Fri, 06 Jan 2017 09:45:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2017/01/06/214578.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214578.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2017/01/06/214578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214578.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214578.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 从appium 1.3.3后,就支持unicode输入,也就是可以输入中文了.<br>实际运行环境：&nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2017/01/06/214578.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2017-01-06 17:45 <a href="http://www.cppblog.com/zdhsoft/archive/2017/01/06/214578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为appium配置gulp es2017 to node 6.9.x</title><link>http://www.cppblog.com/zdhsoft/archive/2016/12/22/214533.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Thu, 22 Dec 2016 03:15:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2016/12/22/214533.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214533.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2016/12/22/214533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214533.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 默认情况下,appium是使用appium-gulp-plugins将代码转由es2015+转换为es5<br>它用上了es2017的特性:await和async<br>但是用它调用gulp watch的时候,常常报错.....<br>现在node.js已经到达了6.9.x,已经99%支持es2015(es6),所以这里重调新调一下&nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2016/12/22/214533.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2016-12-22 11:15 <a href="http://www.cppblog.com/zdhsoft/archive/2016/12/22/214533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>安装appium-selendroid-driver</title><link>http://www.cppblog.com/zdhsoft/archive/2016/12/20/214524.html</link><dc:creator>冬瓜</dc:creator><author>冬瓜</author><pubDate>Tue, 20 Dec 2016 09:34:00 GMT</pubDate><guid>http://www.cppblog.com/zdhsoft/archive/2016/12/20/214524.html</guid><wfw:comment>http://www.cppblog.com/zdhsoft/comments/214524.html</wfw:comment><comments>http://www.cppblog.com/zdhsoft/archive/2016/12/20/214524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zdhsoft/comments/commentRss/214524.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zdhsoft/services/trackbacks/214524.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/zdhsoft/archive/2016/12/20/214524.html'>阅读全文</a><img src ="http://www.cppblog.com/zdhsoft/aggbug/214524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zdhsoft/" target="_blank">冬瓜</a> 2016-12-20 17:34 <a href="http://www.cppblog.com/zdhsoft/archive/2016/12/20/214524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>