问题描述:

We are trying to test the behaviour of our application as it progresses through the different lifecycle states (active, paused, stopped, destroyed) and then at each of those states on the way back from the destroyed state.

The problem we have is that an exception is thrown when calling instrumentation.callActivityOnCreate(testActivity, new Bundle()) to re-create the activity after it has been destroyed.

the exception is as follows

04-16 15:40:20.840 8989-8989/? E/AndroidRuntime﹕ FATAL EXCEPTION: main

java.lang.IllegalStateException: No activity

at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)

at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1039)

at android.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1835)

at android.app.Activity.onCreate(Activity.java:916)

at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:204)

at com.test.TestActivity.onCreate(TestActivity.java:5)

at android.app.Activity.performCreate(Activity.java:5158)

at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1081)

at com.test.TestActivityInstrumentationTest$3.run(TestActivityInstrumentationTest.java:25)

at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1684)

at android.os.Handler.handleCallback(Handler.java:747)

at android.os.Handler.dispatchMessage(Handler.java:92)

at android.os.Looper.loop(Looper.java:151)

at android.app.ActivityThread.main(ActivityThread.java:5152)

at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:511)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

at dalvik.system.NativeStart.main(Native Method)

The test code is below

import android.app.Activity;

import android.app.Instrumentation;

import android.os.Bundle;

import android.test.ActivityInstrumentationTestCase2;

import com.test.TestActivity;

public class TestActivityInstrumentationTest extends ActivityInstrumentationTestCase2<TestActivity> {

public TestActivityInstrumentationTest() {

super(TestActivity.class);

}

public void testActivityOnDestroyedAndStarted() {

final TestActivity testActivity = getActivity();

final Instrumentation instrumentation = getInstrumentation();

instrumentation.runOnMainSync(new Runnable() {

@Override

public void run() {

instrumentation.callActivityOnDestroy(testActivity);

}

});

instrumentation.runOnMainSync(new Runnable() {

@Override

public void run() {

instrumentation.callActivityOnCreate(testActivity, new Bundle());

}

});

}

}

The test activity

import android.support.v4.app.FragmentActivity;

public class TestActivity extends FragmentActivity {

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

}

Does anyone know how we can avoid this?

Thanks

Piers

网友答案:

add a setUp() to instantiate your activity and the tearDown() to handle the finish of the test event. Here I destroy the activities for every test (I think this is what you want to do):

        /**
         * Instance from Solo : provides methods to call the Android user interface.
         * 
         */
        protected Solo solo;

    /**
     * the Activity under test.
     */
    TestActivity activity;

    /*
     * (non-Javadoc)
     * 
     * @see android.test.ActivityInstrumentationTestCase2#setUp()
     */
@Override
protected void setUp() throws Exception {


    activity = getActivity(); 
    // if you are using robotium : 
    solo = new Solo(getInstrumentation(), getActivity());
}

@Override
    public void tearDown() throws Exception {
        // tearDown() is run after a test case has finished.
        // finishOpenedActivities() will finish all the activities that have
        // been opened during the test execution.
        solo.finishOpenedActivities();
        super.tearDown();
    }

Test if you get an Activity instance in the beginning of every test :

 public void testActivityOnDestroyedAndStarted() {
// ensure a valid handle to the activity has been returned
        assertNotNull(activity);
}

when you want to test your onDestroy, try this code :

    instrumentation.runOnMainSync(new Runnable() {
            @Override
            public void run() {
// to get the activity that you are testing
                activity = getActivity();
// check that you are really having a context
assertNotNull(activity);
// and here you are recreating the activity
                instrumentation.callActivityOnCreate(activity, new Bundle());
            }
        });
相关阅读:
Top