【问题标题】:Android Activity Tests - Testing RestartsAndroid Activity 测试 - 测试重启
【发布时间】:2012-01-13 06:06:20
【问题描述】:

在 Android 开发者文档中标题为“添加状态管理测试”的 Testing FundamentalsActivity Testing 部分中,它建议使用以下方法重新启动测试活动:

mActivity.finish();
mActivity = this.getActivity();

在上面两个语句之间添加了一个 sleep 后,我可以看到执行 mActivity = this.getActivity() 时 Activity 没有在屏幕上重绘。我的测试似乎有效,但我很想知道为什么 Activity 没有在屏幕上重绘,因为 API 文档中似乎没有提到这一点。

如果有人能提供任何对此的见解,我将不胜感激。在调用 finish() 方法时,Activity 从屏幕上消失,但在调用 this.getActivity() 时不会重新出现。我也尝试在 getActivity() 之后放置一个 mActivity.setVisible(true),但这没有帮助。

我的代码 sn-p 现在是:

...
mActivity.finish();
Thread.sleep(5000);
mActivity = this.getActivity();
Thread.sleep(5000);
...

我进行了广泛的搜索,但找不到任何解释为什么调用 getActivity() 时 Activity 没有重新出现。

我已经在 Android 2.3.5、2.3.3 和 2.2.2 上对此进行了测试,结果都相同。

【问题讨论】:

  • 感谢您提出这个问题,因为当 UI 线程不在屏幕上时,我的 UIThread 代码将无法运行!

标签: android unit-testing junit


【解决方案1】:

似乎 ActivityInstrumentationTestCase2 类需要一个额外的完成方法,其中必须进行一些清理。同时,您可以通过在完成活动后清理自己来解决此问题。所以改变你的代码如下:

mActivity.finish();
setActivity(null);
mActivity = this.getActivity();

这可以解释如下。 ActivityInstrumentationTestCase2 类中的方法 getActivity 调用 setActivity(a)

public T getActivity() {
    Activity a = super.getActivity();
    if (a == null) {
        // set initial touch mode
        getInstrumentation().setInTouchMode(mInitialTouchMode);
        final String targetPackage = 
            getInstrumentation().getTargetContext().getPackageName();
        // inject custom intent, if provided
        if (mActivityIntent == null) {
            a = launchActivity(targetPackage, mActivityClass, null);
        } else {
            a = launchActivityWithIntent(targetPackage, 
                                         mActivityClass, 
                                         mActivityIntent);
        }
        setActivity(a);
    }
    return (T) a;
}

方法setActivity设置内部变量mActivityIntent。

public void setActivityIntent(Intent i) {
    mActivityIntent = i;
}

第一次调用之后的所有调用现在都将使用新值 mActivityIntent 而不是空值。结果

a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);

将被调用。可能无法以此意图启动您的应用。

请注意,rearDown 方法会进行适当的清理:

protected void tearDown() throws Exception {
    // Finish the Activity off (unless was never launched anyway)
    Activity a = super.getActivity();
    if (a != null) {
        a.finish();
        setActivity(null);
    }
}

【讨论】:

  • 这个答案解决了我的问题,即我的 UI 线程代码在 activity.finish() 之后神秘地没有运行,这破坏了测试 onDestroy 的全部目的。谢谢。
  • 来自文档:终止活动并重新启动它:mActivity.finish(); mActivity = this.getActivity(); 他们真的应该更新文档...
  • 非常感谢您找到这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多