Robotium学习笔记二

来源:互联网 发布:mysql存储过程execute 编辑:程序博客网 时间:2024/05/17 22:21

上一篇记录到了View控件的获取,获取windowManager类中mView属性的值,并从中筛选非DecorView和Activity/Dialog的DecorView,从而获得所有view

在这篇记录中,将记录我对search类的方法源码研究的一些总结

以SearchText为例,通过Solo的searchText(String text)方法调用searcher.searchWithTimeoutFor(TextView.class, text, 0, true, false)方法,在这里有一个计时器,如果到时还未找到,则返回false 方法如下

public boolean searchWithTimeoutFor(Class<? extends TextView> viewClass, String regex, int expectedMinimumNumberOfMatches, boolean scroll, boolean onlyVisible) {final long endTime = SystemClock.uptimeMillis() + TIMEOUT;TextView foundAnyMatchingView = null;while (SystemClock.uptimeMillis() < endTime) {sleeper.sleep();foundAnyMatchingView = searchFor(viewClass, regex, expectedMinimumNumberOfMatches, 0, scroll, onlyVisible);if (foundAnyMatchingView !=null){return true;}}return false;}

在计时时间内调用SearchFor()方法,其中 修改了expectedMinimumNumberOfMatches:这个参数表示搜索目标最小发现数目,当一个界面中有多个控件满足搜索条件,通过此参数可以指定想要获取的是第几个。

public <T extends TextView> T searchFor(final Class<T> viewClass, final String regex, int expectedMinimumNumberOfMatches, final long timeout, final boolean scroll, final boolean onlyVisible) {if(expectedMinimumNumberOfMatches < 1) {expectedMinimumNumberOfMatches = 1;}             <pre class="prettyprint xml"><span class="tag">//定义一个<span class="attribute">Callable</span>给下层<span class="attribute">searchFor</span>使用,可以直接获取到符合条件的控件列表</span>final Callable<Collection<T>> viewFetcherCallback = new Callable<Collection<T>>() {@SuppressWarnings("unchecked")public Collection<T> call() throws Exception {sleeper.sleep();                                //从当前的Android View中获取到符合viewClass的控件列表 ArrayList<T> viewsToReturn = viewFetcher.getCurrentViews(viewClass, true);if(onlyVisible){viewsToReturn = RobotiumUtils.removeInvisibleViews(viewsToReturn);}if(viewClass.isAssignableFrom(TextView.class)) {viewsToReturn.addAll((Collection<? extends T>) webUtils.getTextViewsFromWebView());}return viewsToReturn;}};try {return searchFor(viewFetcherCallback, regex, expectedMinimumNumberOfMatches, timeout, scroll);} catch (Exception e) {throw new RuntimeException(e);}}


在call()方法中调用getCurrentViews()方法,将符合条件的view列表返回

public <T extends View> ArrayList<T> getCurrentViews(Class<T> classToFilterBy, boolean includeSubclasses, View parent) {ArrayList<T> filteredViews = new ArrayList<T>();List<View> allViews = getViews(parent, true);for(View view : allViews){if (view == null) {continue;}Class<? extends View> classOfView = view.getClass();if (includeSubclasses && classToFilterBy.isAssignableFrom(classOfView) || !includeSubclasses && classToFilterBy == classOfView) {filteredViews.add(classToFilterBy.cast(view));}}allViews = null;return filteredViews;}

将定义的viewFetcherCallback 传递给 searchFor()方法,在此方法中完成真正的"查找"

public <T extends TextView> T searchFor(Callable<Collection<T>> viewFetcherCallback, String regex, int expectedMinimumNumberOfMatches, long timeout, boolean scroll) throws Exception {final long endTime = SystemClock.uptimeMillis() + timeout;Collection<T> views;while (true) {final boolean timedOut = timeout > 0 && SystemClock.uptimeMillis() > endTime;if(timedOut){logMatchesFound(regex);return null;}views = viewFetcherCallback.call();for(T view : views){if (RobotiumUtils.getNumberOfMatches(regex, view, uniqueTextViews) == expectedMinimumNumberOfMatches) {uniqueTextViews.clear();return view;}}if(scroll && !scroller.scrollDown()){logMatchesFound(regex);return null; }if(!scroll){logMatchesFound(regex);return null; }}}

首先回调刚刚定义的Callable的call()方法得到所有的符合view的列表,在遍历这个列表调用getNumberOfMatches()方法在查询

public static int getNumberOfMatches(String regex, TextView view, Set<TextView> uniqueTextViews){if(view == null) {return uniqueTextViews.size();}Pattern pattern = null;try{pattern = Pattern.compile(regex);}catch(PatternSyntaxException e){pattern = Pattern.compile(regex, Pattern.LITERAL);}Matcher matcher = pattern.matcher(view.getText().toString());if (matcher.find()){uniqueTextViews.add(view);}if (view.getError() != null){matcher = pattern.matcher(view.getError().toString());if (matcher.find()){uniqueTextViews.add(view);}}if (view.getText().toString().equals("") && view.getHint() != null){matcher = pattern.matcher(view.getHint().toString());if (matcher.find()){uniqueTextViews.add(view);}}return uniqueTextViews.size();}

这个方法使用正则表达式来查找匹配的文本 如果找到就放在uniqueTextView中最后返回列表的大小

最后SearchFor()方法将找到的View返回,最后返回一个true 查找结束


0 0