Tips for using runOnUiThread

I have a class that is under test with Robotium, in it the onPause() method I just clear EditText (I don't need the data that needs to be saved after onPause() ).

So, I have a class that is under the 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 message:

 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 do not get this error.

Then, if I wrap mEdtPassword.setText("") with runOnUiThread() , everything will be fine.

So the questions are:

  • Why I do not have this exception when I use solo.setActivityOrientation() , but I use getInstrumentation().callActivityOnPause(mActivity) , I assume that both do the same.

  • Can I wrap things like mEdtPassword.setText("") in onPause() using runOnUiThread elsewhere for some other reason, or do I just need this for testing purposes?

  • Does this mean that if I want to have tests of my user interface, I need to write more code (for example, run ordinary operations with the UI stream) so that they can run them?

Thanks so much for the clarification.

0
source share
2 answers

The edit is mostly correct, although I believe that you cannot use instrumental methods in the test annotated with @UiThreadTest. This means that your best option is to wrap the toolkit tool in runnable, which you can send to the main thread. eg:

 public void callActivityOnPause(final Activity activity){ getInstrumentation().runOnMainSync(new Runnable() { public void run() { activity.onpause(); } }); } 

I have not tried this code, so it is probably wrong, it just kills time on the train!

0
source

So what I know about this that may help you:

1) Why I do not have this exception when I use solo.setActivityOrientation (), but I use when I use getInstrumentation (). callActivityOnPause (mActivity), I assume that both do the same.

According to javadoc callActivityOnPause ()

Call the onPause () method call. By default, an implementation simply calls this method.

That way, it will call onPause() on its thread, which is not a UI thread. Now, when you set the value and edit the text in Activity onPause() , this will lead to an error. Therefore, the cause of the error is setting the value on your EditText . Since you are not performing any user interface operations in setActivityOrientation() , this does not cause any errors.

2) Can I wrap things like mEdtPassword.setText ("") in onPause () using runOnUiThread somewhere else for other reasons, or do I just need this for testing?

3) Does this mean that if I want to have tests of my interface, I need to write more code (for example, run normal operations in the user interface thread), to do this I can run them?

I would answer two and three together. You do not need to change your activity to make it verifiable. If you are now using a test activity method, then you can put the UiThreadTest annotation in your test method. You can also read the link for more information ..

My knowledge is obtained only from reading a java document. I have not tested it myself. So please let me know how this works.

0
source

All Articles