11

タイトルの通り、runOnUiThread() メソッドと @UiThreadTest アノテーションの違いを説明できる人はいますか? 両方を使用する Android テスト チュートリアル ( http://developer.android.com/tools/testing/activity_test.html ) を読んでいます。それは述べています:

テスト対象のアプリケーションのビューと対話するテスト アプリケーションのコードは、UI スレッドとも呼ばれるメイン アプリケーションのスレッドで実行する必要があります。これを行うには、Activity.runOnUiThread() メソッドを使用します。

と:

@UiThreadTest アノテーションは、UI スレッドで実行されるようにこのメソッドをビルドするよう Android に指示します。これにより、メソッドは、テスト中のアプリケーションでスピナー ウィジェットの状態を変更できます。

runOnUi() メソッドの場合、問題のコードは次のとおりです。

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);
}

@UiThreadTest アノテーションの場合:

@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);     
}

注釈付きテストから注釈を削除し、その内容を runOnUiThread() メソッドに含めることができ、合格するという意味で、それらは交換可能であるように見えます。同様に、もう一方のテストから runOnUiThread() メソッドを削除して @UiThreadTest アノテーションを追加すると、テストは成功します。

違いは何ですか?

さらに、チュートリアルには別のテストが含まれています。

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);
}

このテストもアクティビティと対話しますが、@UiThreadTest アノテーションも runOnUiThread() メソッドも必要としません。どうしてこれなの?

4

1 に答える 1

10

違いはセマンティクスと副作用にあります。

まず、 の存在により、を呼び出すことによって@UiThreadTestまだ作成されていない場合、アクティビティが作成されます。getActivity()

次に、InstrumentatinTestCasegetInstrumentation().runOnMainSync()で、完全なテストを実行するために使用します。

getInstrumentation().runOnMainSync()との違いActivity.runOnUiThread()は、前者は呼び出しが完了するまで待機することです (完全なテストを実行するとき、またはテスト内で何かを呼び出すときに必要です) が、後者はそうしません。

それ以外は、別Handlerの に投稿します (runOnMainSyncの 1 つを使用しActivityThreadActivityインスタンスには独自のものがあります) が、同じ でスケジュールされているため、それは無関係ですMessageQueue

于 2013-10-17T13:24:22.317 に答える