I have a class which is under a test with Robotium, in it’s onPause() method I just clear the EditText (I don’t need the data to be preserved after onPause()).
So I have in a class which is under a test:
@Override
protected void onPause() {
super.onPause();
mEdtPassword.setText("");
}
and testing method:
public void testOnPauseOnStart() {
Activity mActivity = getActivity();
solo.typeText(0, CORRECT_PASSWORD);
getInstrumentation().callActivityOnPause(mActivity);
}
But then I got an error:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:854)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4077)
at android.view.View.invalidate(View.java:10322)
at android.widget.TextView.invalidateRegion(TextView.java:4395)
at android.widget.TextView.invalidateCursor(TextView.java:4338)
at android.widget.TextView.spanChange(TextView.java:7186)
at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:8821)
at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:688)
at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
at android.text.Selection.setSelection(Selection.java:76)
at android.text.Selection.setSelection(Selection.java:87)
at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:302)
at android.widget.TextView.setText(TextView.java:3555)
at android.widget.TextView.setText(TextView.java:3425)
at android.widget.EditText.setText(EditText.java:80)
at android.widget.TextView.setText(TextView.java:3400)
at <package>.ui.CheckPasswordActivity.onPause(CheckPasswordActivity.java:182)
If I use solo.setActivityOrientation(Solo.LANDSCAPE) I don’t get this error.
Then if I wrap the mEdtPassword.setText("") with runOnUiThread() everything is fine.
So the questions are:
-
Why I don’t have this exception when I use
solo.setActivityOrientation()but I do when I usegetInstrumentation().callActivityOnPause(mActivity), I presume both are doing the same thing. -
Shall I wrap things like
mEdtPassword.setText("")inonPause()withrunOnUiThreadsomewhere else for some other reasons or I just need it for testing purposes? -
Does it mean if I want to have tests of my UI I need to write more code (like running ordinar operations on UI thread) to make it possible to run them?
Thank you very much for clarification.
Praful is mostly correct although I believe you are unable to use instrumentations methods within a test annotated with @UiThreadTest. This means your best option is in fact to wrap instrumentations method in a runnable that you can post to the main thread. for instance:
I havent tried this code, so its probably wrong, just killing time on the train!