As the title, can anyone explain the difference between the runOnUiThread() method and the @UiThreadTest annotation? I've been reading through the Android testing tutorial (http://developer.android.com/tools/testing/activity_test.html) which uses both. It states:
Code in a test application that interacts with a View of the application under test must run in the main application's thread, also known as the UI thread. To do this, you use the Activity.runOnUiThread() method
and:
The @UiThreadTest annotation tells Android to build this method so that it runs on the UI thread. This allows the method to change the state of the spinner widget in the application under test.
For the runOnUi() method, the code in question is
public void testASpinnerUI()
{
mActivity.runOnUiThread(
new Runnable()
{
@Override
public void run()
{
mSpinner.requestFocus();
mSpinner.setSelection(INITIAL_POSITION);
}// end of run
} // end of runnable
); //end of runOnUiThread
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
for (int i = 0; i < TEST_POSITION; i++)
{
this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
}
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
mPos = mSpinner.getSelectedItemPosition();
mSelection = (String) mSpinner.getItemAtPosition(mPos);
TextView resultView = (TextView) mActivity.findViewById(com.android.example.spinner.R.id.SpinnerResult);
String resultText = (String) resultView.getText();
assertEquals(resultText, mSelection);
}
and for the @UiThreadTest annotation:
@UiThreadTest
public void testStatePause()
{
Instrumentation mInstr = this.getInstrumentation();
mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
mInstr.callActivityOnPause(mActivity);
mActivity.setSpinnerPosition(0);
mActivity.setSpinnerSelection("");
mInstr.callActivityOnResume(mActivity);
int currentPosition = mActivity.getSpinnerPosition();
String currentSelection = mActivity.getSpinnerSelection();
assertEquals(TEST_STATE_PAUSE_POSITION, currentPosition);
assertEquals(TEST_STATE_PAUSE_SELECTION, currentSelection);
}
They appear to be interchangeable, in the sense that I can remove the annotation from the annotated test and include its contents in a runOnUiThread() method and it passes. Similarly, I can remove the runOnUiThread() method from the other test and add the @UiThreadTest annotation and it passes.
So what's the difference?
Additionally, the tutorial includes another test:
public void testStateDestroy()
{
mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
mActivity.finish();
mActivity = getActivity();
int currentPosition = mActivity.getSpinnerPosition();
String currentSelection = mActivity.getSpinnerSelection();
assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
}
This test also interacts with the activity but requires neither the @UiThreadTest annotation or a runOnUiThread() method. Why is this?
Sometimes Main thread performs some heavy operations. if user wants to add some extra operations on UI, it will get load and provides ANR. Using runOnUiThread going to do back ground operations on worker thread and update the result on main thread. This example demonstrate about How do we use runOnUiThread in Android.
runOnUiThread. Helper method for running part of a method on the UI thread.
The difference is in semantics and side effects.
First, the presence of @UiThreadTest
causes the activity to be created if it hasn't been already by calling getActivity()
.
Then, in InstrumentatinTestCase, it uses getInstrumentation().runOnMainSync()
to run the full test.
The difference between getInstrumentation().runOnMainSync()
and Activity.runOnUiThread()
is that the former waits for the call to finish (needed when running a full test or, you know, calling things inside a test) while the latter doesn't.
Other than that, they post to different Handler
s (runOnMainSync
uses the one from ActivityThread
, while the Activity
instance has its own) but that's irrelevant, since they're getting scheduled on the same MessageQueue
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With