Robotium学习笔记四
来源:互联网 发布:金盾网络电视台正规吗 编辑:程序博客网 时间:2024/05/20 18:55
在这篇记录中我将完成solo类中其他未记录的方法的学习笔记,主要是Click,和Type/Enter,那么我最先开始的是Click这个类型的方法,其实这个操作的原理并不难理解,主要是拿到控件,再通过控件上的坐标点发送点击事件,下面是代码
public void clickOnText(String text) {clicker.clickOnText(text, false, 1, true, 0);}
调用Clicker类中的 clickOnText()
public void clickOnText(String regex, boolean longClick, int match, boolean scroll, int time) {TextView textToClick = waiter.waitForText(regex, match, Timeout.getSmallTimeout(), scroll, true, false);if (textToClick != null) {clickOnScreen(textToClick, longClick, time);}else {if(match > 1){Assert.fail(match + " matches of text string: '" + regex + "' are not found!");}else{ArrayList<TextView> allTextViews = RobotiumUtils.removeInvisibleViews(viewFetcher.getCurrentViews(TextView.class, true));allTextViews.addAll((Collection<? extends TextView>) webUtils.getTextViewsFromWebView());for (TextView textView : allTextViews) {Log.d(LOG_TAG, "'" + regex + "' not found. Have found: '" + textView.getText() + "'");}allTextViews = null;Assert.fail("Text string: '" + regex + "' is not found!");}}}
这个方法中首先还是获取参数中传过来的控件这个方法没得可说,和前面的Search是一样的,拿到控件后就是点击了,调用 clickOnScreen()
public void clickOnScreen(View view, boolean longClick, int time) {if(view == null)Assert.fail("View is null and can therefore not be clicked!");float[] xyToClick = getClickCoordinates(view);float x = xyToClick[0];float y = xyToClick[1];if(x == 0 || y == 0){sleeper.sleepMini();try {view = viewFetcher.getIdenticalView(view);} catch (Exception ignored){}if(view != null){xyToClick = getClickCoordinates(view);x = xyToClick[0];y = xyToClick[1];}}if (longClick)clickLongOnScreen(x, y, time, view);elseclickOnScreen(x, y, view);}
这个方法主要是将View控件转化为坐标点,然后传给clickOnScreen()的重载形式,其中getClickCoordinates(view);这个方法就是要得到view的中心点的坐标,再加上view在屏幕上的坐标,得到了一个view中心点的坐标,(这里开始我不太明白但是也是在看了前辈的博文后才有所理解),算了不能犯懒我还是详细记录一下吧, view.getLocationOnScreen()这个方法是得到view控件左边和上边 距离屏幕左边和屏幕上边的距离从而得到坐标,再加上view内部中心点的的坐标,得到view中心点在屏幕上的绝对坐标
private float[] getClickCoordinates(View view){sleeper.sleep(MINI_WAIT);int[] xyLocation = new int[2];float[] xyToClick = new float[2];view.getLocationOnScreen(xyLocation);final int viewWidth = view.getWidth();final int viewHeight = view.getHeight();final float x = xyLocation[0] + (viewWidth / 2.0f);float y = xyLocation[1] + (viewHeight / 2.0f);xyToClick[0] = x;xyToClick[1] = y;return xyToClick;}
得到坐标后发送个体clickOnScreen()重载方法这里有一个 LongClick的值来判断 是点击还是长按
public void clickOnScreen(float x, float y, View view) {boolean successfull = false;int retry = 0;SecurityException ex = null;while(!successfull && retry < 10) {long downTime = SystemClock.uptimeMillis();long eventTime = SystemClock.uptimeMillis();MotionEvent event = MotionEvent.obtain(downTime, eventTime,MotionEvent.ACTION_DOWN, x, y, 0);MotionEvent event2 = MotionEvent.obtain(downTime, eventTime,MotionEvent.ACTION_UP, x, y, 0);try{inst.sendPointerSync(event);inst.sendPointerSync(event2);successfull = true;}catch(SecurityException e){ex = e;dialogUtils.hideSoftKeyboard(null, false, true);sleeper.sleep(MINI_WAIT);retry++;View identicalView = viewFetcher.getIdenticalView(view);if(identicalView != null){float[] xyToClick = getClickCoordinates(identicalView);x = xyToClick[0]; y = xyToClick[1];}}}if(!successfull) {Assert.fail("Click at ("+x+", "+y+") can not be completed! ("+(ex != null ? ex.getClass().getName()+": "+ex.getMessage() : "null")+")");}}
到这里就一目了然了,看到了使用Instrumentation发送 MotionEvent事件完成点击,其实长按和点击是差不多的就是Key_dwon 然后sleep.
下面来看看type 先看代码
public void typeText(final EditText editText, final String text){if(editText != null){inst.runOnMainSync(new Runnable(){public void run(){editText.setInputType(InputType.TYPE_NULL);}});clicker.clickOnScreen(editText, false, 0);dialogUtils.hideSoftKeyboard(editText, true, true);boolean successfull = false;int retry = 0;while(!successfull && retry < 10) {try{inst.sendStringSync(text);successfull = true;}catch(SecurityException e){dialogUtils.hideSoftKeyboard(editText, true, true);retry++;}}if(!successfull) {Assert.fail("Text can not be typed!");}}}}这里其实没有什么太多难度,此方法首先设置输入类型deitText..setInputType(0),然后把焦点数值在EditText上,隐藏键盘,这些都是准备工作,最好开始输入,又事强大的Instrumentation来发送事件
,这里有一点很重要typeText 和EnterText在方法调用时其实是类似的,但是有一些区别具体请看源码
typeText调用inst.sendStringSync(text);
public void sendStringSync(String text) { if (text == null) { return; } KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); KeyEvent[] events = keyCharacterMap.getEvents(text.toCharArray()); if (events != null) { for (int i = 0; i < events.length; i++) { // 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. sendKeySync(KeyEvent.changeTimeRepeat(events[i], SystemClock.uptimeMillis(), 0)); } } }
可以注意到 再输入时将text转为了 char数组 一个一个的输入,让我们类对比EnterText方法 ,这个方法直接调用EditText的setText的方法editText.setText(text);
public final void setText(CharSequence text) { setText(text, mBufferType); }
这个方法就是一下把文本全部写上去没有发送KeyEvent事件,这一点是需要注意的
到此处Solo类的绝大多数类型都已经统计完毕,这是我对Robotium原理的一些简单理解,还有很多不对的和不清晰的地方 比如为什么要用 OnMainThread和OnUiThread等希望大家指出
0 0
- Robotium学习笔记四
- Robotium学习笔记
- robotium学习笔记
- Robotium学习笔记一
- Robotium学习笔记二
- Robotium学习笔记三
- Robotium学习笔记一
- Robotium学习笔记二
- Robotium学习笔记三
- Robotium学习笔记三
- Robotium学习笔记二
- Robotium学习笔记一
- Robotium学习笔记
- Robotium学习笔记二
- Robotium学习笔记三
- Robotium学习笔记五
- robotium学习笔记
- robotium学习笔记(二)----问题
- 为以后纪念---今天开通的
- selection dose not contain a main type
- Java与C/C++有什么区别
- DML DDL DCL区别
- UNP 卷一的服务器时间获取例子
- Robotium学习笔记四
- 挑战jquery(一)实现水平幻灯片
- Linux内核分析——分析C程序的反汇编内容
- ZOJ 1636 Evaluate Matrix Sum
- leetcode Integer to Roman
- poj 一类开关问题
- 反汇编代码分析
- 如何选择项目语言(项目笔记)
- lecture13-BP算法的讨论和置信网