getActivity()调用导致RuntimeException:无法启动意图Intent act = android.intent.action.MAIN [英] getActivity() call causes RuntimeException: Could not launch intent Intent act=android.intent.action.MAIN

查看:229
本文介绍了getActivity()调用导致RuntimeException:无法启动意图Intent act = android.intent.action.MAIN的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已更新#1:更多信息添加到此帖子的末尾



我是Android开发和测试的新手。 p>

我有三个Espresso测试。第一次测试通过,但第二个测试通过,但是在第二次测试之前调用setUp()方法中的getActivity()总是失败:


Blockquote
java.lang.RuntimeException:在45秒内无法启动意图Intent {act = android.intent.action.MAIN flg = 0x10000000 cmp = my.packagename / .ActivityMain}。 ...


第三个测试通过



我不有任何长时间运行的操作,动画或网络呼叫创建。我可以点击我的应用程序中的所有菜单项,手动重复测试流程,没有问题。



由于某种原因,第一个测试中断下一个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();
私人活动活动;

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


@Before
public void setUp()throws异常{
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(选择乐队系统);
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);
//此测试不会运行
}


public void testThird(){
Log.d(TAG,testThird);
//此测试将通过
}

// ------------------帮助方法----- ----------------------------------

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

openActionBarOverflowOrOptionsMenu(getInstrumentation()
.getTargetContext());

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

私人匹配器< BandSystem> hasName(final String name){
Log.d(TAG,hasName);

返回新的BaseMatcher< BandSystem>(){
@Override
public boolean matches(final Object item){
final BandSystem foo =(BandSystem)
返回名称== foo.getName();
}

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

}

错误跟踪:

  java.lang.RuntimeException:无法启动意图Intent {act = android.intent.action.MAIN flg = 0x10000000 cmp = net.humblegames。 45秒内的体温计算器/ .ActivityMain}。主线程也许在合理的时间内没有闲置?可能会有动画或不断重画画面的东西。还是活动正在进行网络呼叫创建?请参阅threaddump日志。为了参考上次事件队列空闲的时间,您的活动启动请求之前为1395582828351,现在最后一次队列空闲为:1395582830169.如果这些数字相同,您的活动可能会占用事件队列。 
com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.startActivitySync(GoogleInstrumentation.java:277)
在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)
在android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
在android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
在android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
在com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner.onStart(GoogleInstrumentationTestRunner.java:167)
在android.app.Instrumentation $ InstrumentationThread.r un(Instrumentation.java:1701)





更新#1



我为该项目创建了一个干净的eclipse项目和一个干净的Espresso测试。在Espresso测试运行期间,我能够重现同样的错误(但我仍然不确定此错误的原因是否与我的真实应用程序相同):



目标app有3个活动(主,二,三)。用户通过点击菜单项导航:主活动开始第二个,第二个活动开始第三个。



我发现如果我调用clickMenuItem()(见下文) AND Thread.sleep(500)在第一次测试中会导致在第二次测试之前的getActivity()调用中的setUp()中崩溃。如果睡眠超时小于0.5秒,则不会发生崩溃。



同时如果调用Thread.sleep(10000)而不调用clickMenuItem()也没有崩溃。它将在第一次测试中成功休息10秒钟,并且还将通过第二个测试。






测试代码:

  public class MainActivityTest extends 
ActivityInstrumentationTestCase2< MainActivity> {

private String TAG = getClass()。getSimpleName();
私人活动活动;

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(开始第二个活动);

clickMenuItem(启动第三个活动);

Thread.sleep(500);
}

public void testSecond(){
Log.d(TAG,testSecond);
//此测试不会运行}


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(菜单菜单){
//扩充菜单;如果存在,则会将项目添加到操作栏。
getMenuInflater()。inflate(R.menu.main,menu);
返回true; }

@Override
public boolean onOptionsItemSelected(MenuItem item){
//处理项目选择
开关(item.getItemId()){
case R.id.action_start_second_activity:
Intent intent = new Intent(this,SecondActivity.class);
startActivity(intent);
返回true;

默认值:
返回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(菜单菜单){
//扩充菜单;如果存在,则会将项目添加到操作栏。
getMenuInflater()。inflate(R.menu.second,menu);
返回true; }

@Override
public boolean onOptionsItemSelected(MenuItem item){
//处理项目选择
开关(item.getItemId()){
case R.id.action_start_third_activity:
Intent intent = new Intent(this,ThirdActivity.class);
startActivity(intent);
返回true;

默认值:
返回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(菜单菜单){
//扩充菜单;如果存在,则会将项目添加到操作栏。
getMenuInflater()。inflate(R.menu.third,menu);
返回true;
}


解决方案

我找到了解决方法。我在tearDown()方法中添加了多次重复按钮的代码,以关闭所有以前打开的活动。不幸的是,我没有发现另一种方法如何关闭Espresso中所有打开的活动。机器人有一个非常方便的方法为此目的solo.finishOpenedActivities()。

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

goBackN();

super.tearDown();
}

private void goBackN(){
final int N = 10; //打多少次按钮
尝试{
for(int i = 0; i< N; i ++)
Espresso.pressBack();
} catch(com.google.android.apps.common.testing.ui.espresso.NoActivityResumedException e){
Log.e(TAG,Closed all activities,e);
}
}


Updated #1: more info added to the end of this post

I'm new to Android development and testing.

I have three Espresso tests. First test passes, but the second one will not run because the call to getActivity() in setUp() method before the second test always fails:

Blockquote java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=my.packagename/.ActivityMain } within 45 seconds. ...

The third test passes.

I don't have any long running operations, animations or network calls on creation. I can click through all menu items in my app manually repeating the test flow without issues.

For some reason the first test "breaks" next getActivity() call in setUp() before the second test. All following tests (after the second test) will run OK.

I found similar question but it looks like it wasn't resolved and it has a little bit different problem.

Test code:

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

}

Error trace:

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)



Update #1

I created a clean eclipse project and a clean Espresso test for that project. I was able to reproduce the same error during Espresso test run (but I'm still unsure if the cause of this error is the same in my real app):

Target app has 3 activities (main, second, third). User navigates between them by clicking menu items: main activity starts the second, the second activity starts the third.

I found that if I call clickMenuItem() (see below) AND Thread.sleep(500) in the first test this causes crash in setUp() in getActivity() call before the second test. If timeout in sleep is less than 0.5 sec there is no crash.

At the same time if call Thread.sleep(10000) and don't call clickMenuItem() there is no crash also. It will successfully sleep for 10 seconds in the first test and will also pass the second one.



Test code:

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



Target code:

Main Activity:

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

Second Activity:

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

Third Activity:

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

解决方案

I found a workaround. I added code that hits back button multiple times in the tearDown() method to close all previously opened activities. Unfortunately I didn't found another method how to close all opened activities in Espresso. Robotium has a very convenient method for that purpose solo.finishOpenedActivities().

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

    goBackN();

    super.tearDown();
}

private void goBackN() {
    final int N = 10; // how many times to hit back button
    try {
        for (int i = 0; i < N; i++)
            Espresso.pressBack();
    } catch (com.google.android.apps.common.testing.ui.espresso.NoActivityResumedException e) {
        Log.e(TAG, "Closed all activities", e);
    }
}

这篇关于getActivity()调用导致RuntimeException:无法启动意图Intent act = android.intent.action.MAIN的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆