启动活动超时,因为活动启动另一个活动

时间:2017-03-06 13:25:26

标签: android android-espresso

我的活动' MainActivity'在某些情况下,我们需要开始另一项活动。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...
    if (condition) {
        startActivity(new Intent(this, AnotherActivity.class))
    }
}

我想在MainActivity上运行测试,认为AnotherActivity是以这些条件开始的。

我的Espresso测试无法启动MainActivity,因为它似乎等待MainActivity出现在屏幕上。自从我开始其他活动以来,这不会发生。该活动通过ActivityTestRule启动。

运行Espresso测试时出现以下异常:

java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.djoglobal.corebelt.debug/com.djo.compex.corebelt.ui.MainActivity } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1488804986217 and now the last time the queue went idle was: 1488804986217. If these numbers are the same your activity might be hogging the event queue.
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:360)
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:219)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:268)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at tools.fastlane.screengrab.locale.LocaleTestRule$1.evaluate(LocaleTestRule.java:32)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)

如果我开始使用#AndanActivity'我会有同样的行为。在onResume。

我正在使用Espresso 2.2.1

有任何想法测试这种情况吗?

3 个答案:

答案 0 :(得分:0)

您可以将活动发布到Handler

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    if (condition) {
        final int millisUntilLaunch = 500;

        final Handler handler = new Handler();

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startActivity(new Intent(this, AnotherActivity.class));
            }
        }, millisUntilLaunch);
    }
}

答案 1 :(得分:0)

我已使用Espresso Intents来存储已启动活动的意图,以防止它被显示。

在我的情况下,如果用户没有登录,则在MainActivity的onCreate()中启动LoginActivity:

Account account = AccountUtils.getAccount(this);
if (account == null) {
    startActivity(this, LoginActivity.class);
    finish();
    return;
}

Espresso测试验证LoginActivity是否已启动:

@Test
public void startsLoginActivityImmediately() {
    Intents.init();

    // Stub the login intent to prevent LoginActivity from being displayed.
    // This helps to fix the Espresso timeout exception.
    Matcher<Intent> loginIntent = hasComponent(LoginActivity.class.getName());
    intending(loginIntent).respondWith(new Instrumentation.ActivityResult(0, null));

    mActivityRule.launchActivity(null);
    intended(hasComponent(LoginActivity.class.getName()));

    Intents.release();
}

我希望这种方法能解决你的问题。

答案 2 :(得分:0)

我觉得你在某处有问题: mActivityTestRule.launchActivity(null); 当我通过null时,我遇到了与您相同的错误。

这是我的代码示例,它适用于每个场景(请参阅注释掉的部分):

@RunWith(AndroidJUnit4.class)
public class MyTest {

    @Rule
    public ActivityTestRule<TestActivity1> mActivityTestRule = new ActivityTestRule<>(TestActivity1.class);

    @Before
    public void setup() {
        Intents.init();
    }

    @After
    public void tearDown() {
        Intents.release();
    }

    @Test
    public void test() {
        Intent intent = new Intent();
        mActivityTestRule.launchActivity(intent);
        intended(hasComponent(TestActivity2.class.getName()));
    }
}

...

public class TestActivity1 extends Activity{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        setTitle("first");

        if (isConditionMatch()) {
            startActivity(new Intent(this, TestActivity2.class));
        }
    }
}

此外,您可以尝试使用方法调用替换startActivity(new Intent(this, TestActivity2.class));来实现单元测试,并将其放入演示者或类似的内容。

相关问题