警报对话框崩溃 Android 测试 - "Can't create handler inside thread that has not called Looper.prepare()"

Alert Dialog crashes Android test - "Can't create handler inside thread that has not called Looper.prepare()"

    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    builder.setMessage(message)
            .setCancelable(false)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    login(activity);
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {

                    dialog.cancel();
                    activity.finish();
                }
            });
    AlertDialog alert = builder.create(); // Crash
    alert.show();

应用程序 运行 很好,当我 运行 它正常时显示警报对话框,但是当我 运行 它在仪器测试中时,它在 builder.create 第一行:

        final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);

除此之外:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

这将关闭应用程序,然后测试失败,因为没有任何 activity:

android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?

这是一个线程问题,但这不是我根据答案所期望的 here:

To verify if dialog appears you can simply check if View with a text that present inside the dialog is shown:

onView(withText("dialogText")).check(matches(isDisplayed()));

我不明白如果应用程序在创建对话框之前崩溃,我应该如何检查文本是否显示。

编辑:

    mActivityRule.launchActivity(intent);

    mActivityRule.getActivity().showOptionDialog();

    onView(withText(mActivityRule.getActivity().getString(R.string.dialogText))).check(matches(isDisplayed()));

一些可能对您有帮助的事情...

  1. 在 Espresso 测试中调用 <code>mActivityRule.getActivity().showOptionDialog(); 不是 'Espresso' 方式。除非您的测试被正确注释,否则它不会在 UI 线程上 运行ning,因此在这种情况下,您正在从 Instrumentation 线程调用应该在 UI 线程上完成的操作.您可以通过执行以下操作来解决此问题:

    rule.runOnUiThread(new Runnable() { @覆盖 public无效运行(){ mActivityRule.getActivity().showOptionDialog(); } });

这样做可能需要您构建自己的同步逻辑,以确保未来的 Espresso 语句不会运行在此发生之前。

使用 Espresso 进行测试的更好方法是在通常会调用 showOptionsDialog().

的 UI 控件上使用 onView(XXX).perform(click())
  1. 此外,您不需要自己解析传递给 withText() 的字符串,您可以只使用字符串资源 ID,但这不是您所看到的问题的原因.