Robotium学习笔记二

上一篇记录到了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 查找结束


内容概要:本文《2025年全球AI Coding市场洞察研究报告》由亿欧智库发布,深入分析了AI编程工具的市场现状和发展趋势。报告指出,AI编程工具在2024年进入爆发式增长阶段,成为软件开发领域的重要趋势。AI编程工具不仅简化了代码生成、调试到项目构建等环节,还推动编程方式从人工编码向“人机协同”模式转变。报告详细评估了主流AI编程工具的表现,探讨了其商业模式、市场潜力及未来发展方向。特别提到AI Agent技术的发展,使得AI编程工具从辅助型向自主型跃迁,提升了任务执行的智能化和全面性。报告还分析了AI编程工具在不同行业和用户群体中的应用,强调了其在提高开发效率、减少重复工作和错误修复方面的显著效果。最后,报告预测2025年AI编程工具将在精准化和垂直化上进一步深化,推动软件开发行业进入“人机共融”的新阶段。 适合人群:具备一定编程基础,尤其是对AI编程工具有兴趣的研发人员、企业开发团队及非技术人员。 使用场景及目标:①了解AI编程工具的市场现状和发展趋势;②评估主流AI编程工具的性能和应用场景;③探索AI编程工具在不同行业中的具体应用,如互联网、金融、游戏等;④掌握AI编程工具的商业模式和盈利空间,为企业决策提供参考。 其他说明:报告基于亿欧智库的专业研究和市场调研,提供了详尽的数据支持和前瞻性洞察。报告不仅适用于技术从业者,也适合企业管理者和政策制定者,帮助他们在技术和商业决策中更好地理解AI编程工具的价值和潜力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值