Вызов getActivity () вызывает RuntimeException: не удалось запустить намерение Intent act = android.intent.action.MAIN

Обновлено # 1: больше информации добавлено в конце этого поста

Я новичок в разработке и тестировании Android.

У меня есть три теста эспрессо. Первый тест проходит, но второй не будет запущен, потому что вызов getActivity () в методе setUp () перед вторым тестом всегда терпит неудачу:

Цитата java.lang.RuntimeException: Не удалось запустить намерение Intent {act = android.intent.action.MAIN flg = 0x10000000 cmp = my.packagename / .ActivityMain} в течение 45 секунд. ...

Третий тест проходит.

У меня нет никаких длительных операций, анимаций или сетевых вызовов при создании. Я могу просмотреть все пункты меню в моем приложении, вручную повторив тестовый цикл без проблем.

По какой-то причине первый тест «прерывает» следующий вызов getActivity () в setUp () перед вторым тестом. Все последующие тесты (после второго теста) будут выполняться нормально.

я нашеланалогичный вопрос, но похоже, что он не был решен, и у него есть немного другая проблема.

Тестовый код:

import static com.google.android.apps.common.testing.ui.espresso.Espresso.onData;
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
import static com.google.android.apps.common.testing.ui.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isDisplayed;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import net.humblegames.bodylasticscalculator.ActivityMain;
import net.humblegames.bodylasticscalculator.R;
import net.humblegames.bodylasticscalculator.applogic.BandSystem;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;

import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;

public class MenuNavigationTestExperiment extends
        ActivityInstrumentationTestCase2<ActivityMain> {

    private String TAG = getClass().getSimpleName();
    private Activity activity;

    public MenuNavigationTestExperiment() {
        super(ActivityMain.class);
    }


    @Before
    public void setUp() throws Exception {
        Log.d(TAG, "SETUP");
        activity = getActivity();

        super.setUp();
    }

    @After
    public void tearDown() throws Exception {
        Log.d(TAG, "TEARDOWN");

        super.tearDown();
    }


    public void testFirst() {
        Log.d(TAG, "testFirst");

        clickMenuItem("Select band system");
        onData(allOf(is(instanceOf(BandSystem.class)), hasName("MMA Training")))
        .onChildView(withId(R.id.label)).perform(click());

        clickMenuItem("About");
        onView(withId(R.id.about_webview)).check(matches(isDisplayed()));
    }

    public void testSecond() {
        Log.d(TAG, "testSecond");
        // this test will not run
    }


    public void testThird() {
        Log.d(TAG, "testThird");
        // this test will pass
    }

    // ------------------ HELPER METHODS ---------------------------------------

    private void clickMenuItem(String menuItem) {
        Log.d(TAG, "clickMenuItem");

        openActionBarOverflowOrOptionsMenu(getInstrumentation()
                .getTargetContext());

        onView(withText(menuItem)).perform(click());
    }

    private Matcher<BandSystem> hasName(final String name) {
        Log.d(TAG, "hasName");

        return new BaseMatcher<BandSystem>() {
            @Override
            public boolean matches(final Object item) {
                final BandSystem foo = (BandSystem) item;
                return name == foo.getName();
            }

            @Override
            public void describeTo(final Description description) {
                description.appendText("getName should return ").appendValue(
                        name);
            }
        };
    }

}

Трассировка ошибок:

java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=net.humblegames.bodylasticscalculator/.ActivityMain } 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 1395582828351 and and now the last time the queue went idle was: 1395582830169. If these numbers are the same your activity might be hogging the event queue.
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.startActivitySync(GoogleInstrumentation.java:277)
at android.test.InstrumentationTestCase.launchActivityWithIntent(InstrumentationTestCase.java:119)
at android.test.InstrumentationTestCase.launchActivity(InstrumentationTestCase.java:97)
at android.test.ActivityInstrumentationTestCase2.getActivity(ActivityInstrumentationTestCase2.java:104)
at net.humblegames.bodylasticscalculator.test.MenuNavigationTestExperiment.setUp(MenuNavigationTestExperiment.java:42)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)


Обновление № 1

Я создал чистый проект Eclipse и чистый тест Espresso для этого проекта. Я смог воспроизвести ту же ошибку во время запуска теста Espresso (но я все еще не уверен, является ли причина этой ошибки той же самой в моем реальном приложении):

Целевое приложение имеет 3 вида деятельности (основное, второе, третье). Пользователь перемещается между ними, нажимая пункты меню: основное действие начинается вторым, второе действие начинается третьим.

Я обнаружил, что если я вызываю clickMenuItem () (см. Ниже) И Thread.sleep (500) в первом тесте, это вызывает сбой в setUp () в вызове getActivity () перед вторым тестом. Если время ожидания менее 0,5 с, сбоя не происходит.

В то же время, если вызвать Thread.sleep (10000) и не вызывать clickMenuItem (), сбоя также не происходит. В первом тесте он будет успешно спать 10 секунд, а также пройдет второй.


Тестовый код:

public class MainActivityTest extends
        ActivityInstrumentationTestCase2<MainActivity> {

    private String TAG = getClass().getSimpleName();
    private Activity activity;

    public MainActivityTest() {
        super(MainActivity.class);    }

    public void setUp() throws Exception {
        Log.d(TAG, "SETUP");
        activity = getActivity();

        super.setUp();       }

    public void tearDown() throws Exception {
        Log.d(TAG, "TEARDOWN");

        super.tearDown();    }


    public void testFirst() throws InterruptedException {
        Log.d(TAG, "testFirst");

        clickMenuItem("Start second activity");

        clickMenuItem("Start third activity");

        Thread.sleep(500);
    }

    public void testSecond() {
        Log.d(TAG, "testSecond");
        // this test will not run     }


    private void clickMenuItem(String menuItem) {
        Log.d(TAG, "clickMenuItem");

        openActionBarOverflowOrOptionsMenu(getInstrumentation()
                .getTargetContext());

        onView(withText(menuItem)).perform(click());      }    }


Целевой код:

Основная деятельность:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);         }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;        }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.action_start_second_activity:
            Intent intent = new Intent(this, SecondActivity.class);
            startActivity(intent);
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }       }        }

Второе занятие:

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);       }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.second, menu);
        return true;        }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.action_start_third_activity:
            Intent intent = new Intent(this, ThirdActivity.class);
            startActivity(intent);
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }       }   }

Третье мероприятие:

public class ThirdActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.third, menu);
        return true;    }
}

Ответы на вопрос(5)

Ваш ответ на вопрос