在测试自动化的过程中,有时经常需要获取Toast的String来作检验。
当应用中调用Toast的makeText()方法时,系统做了如下事情:
由上可知,调用makeText时,系统初始化了个TextView,且这个TextView的id系统的id,为:com.android.internal.R.id.message
知道了Toast的本质是一个TextView,且其id是com.android.internal.R.id.message后,要获取它的String就好办了。
看robotium中的getView()方法的实现:
好吧,天冷又水了一篇。。
在robotium中,我们知道可以通过solo.getView("message")方法获取Toast的TextView,然后得到其String值,那么其内部是怎么实现的呢。
首先看下我们一般是怎么调用Toast的:
- Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
- public static Toast makeText(Context context, CharSequence text, int duration) {
- Toast result = new Toast(context);
- LayoutInflater inflate = (LayoutInflater)
- context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
- TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
- tv.setText(text);
- result.mNextView = v;
- result.mDuration = duration;
- return result;
- }
知道了Toast的本质是一个TextView,且其id是com.android.internal.R.id.message后,要获取它的String就好办了。
看robotium中的getView()方法的实现:
- /**
- * Returns a {@code View} with a given id.
- *
- * @param id the id of the {@link View} to return
- * @param index the index of the {@link View}. {@code 0} if only one is available
- * @return a {@code View} with a given id
- */
- public View getView(String id, int index){
- View viewToReturn = null;
- Context targetContext = instrumentation.getTargetContext();
- String packageName = targetContext.getPackageName();
- int viewId = targetContext.getResources().getIdentifier(id, "id", packageName);
- if(viewId != 0){
- viewToReturn = getView(viewId, index, TIMEOUT);
- }
- if(viewToReturn == null){
- int androidViewId = targetContext.getResources().getIdentifier(id, "id", "android");
- if(androidViewId != 0){
- viewToReturn = getView(androidViewId, index, TIMEOUT);
- }
- }
- if(viewToReturn != null){
- return viewToReturn;
- }
- return getView(viewId, index);
- }
robotium为了方便以String形式的id来查找控件,因此封装了个如上getView(String id, int index)通过String id来获取View的方法,在这个方法中通过getIdentifier把String形式的id转变成int型的id,然后再根据Int型的id来查找控件,由上文我们已经知道Toast的id了,因此我们可以简单地通过solo.getView("message")来获取Toast的TextView。
当然了,为了实际项目中能更好地获取Toast,我们可以自己再封装一下:
- /**
- * 获取Toast的String值
- * @return
- */
- public String getToast(int timeout){
- TextView toastTextView = null;
- String toastText = "";
- long endTime = SystemClock.uptimeMillis() + timeout;
- while(SystemClock.uptimeMillis() < endTime){
- toastTextView = (TextView) getView("message", 0);
- if(null != toastTextView){
- toastText = toastTextView.getText().toString();
- break;
- }else {
- sleeper.sleepMini();
- }
- }
- return toastText;
- }