Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取Android Instrumentation测试的当前活动_Java_Android_Automated Tests_Junit3 - Fatal编程技术网

Java 获取Android Instrumentation测试的当前活动

Java 获取Android Instrumentation测试的当前活动,java,android,automated-tests,junit3,Java,Android,Automated Tests,Junit3,我的Android应用程序上的MainActivity检查用户是否已登录(此信息存储在SharedReferences中),如果未登录,则将用户带到LoginActivity。我尝试使用以下代码来测试这一点 public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private static final int TIME_OUT = 5000; /* milisec

我的Android应用程序上的MainActivity检查用户是否已登录(此信息存储在SharedReferences中),如果未登录,则将用户带到LoginActivity。我尝试使用以下代码来测试这一点

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

private static final int TIME_OUT = 5000; /* miliseconds */

private MainActivity mMainActivity;
private Instrumentation mInstrumentation;
private SharedPreferences mLoginPrefs;

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

protected void setUp() throws Exception {
    super.setUp();

    setActivityInitialTouchMode(false);

    mMainActivity = getActivity();
    mInstrumentation = getInstrumentation();
    mLoginPrefs = mInstrumentation.getTargetContext().getSharedPreferences(LoginActivity.PREFS_NAME, Context.MODE_PRIVATE);

    SharedPreferences.Editor editor = mLoginPrefs.edit();
            // User is not logged in, so it should be redirect to LoginActivity
    editor.putBoolean("logged_in", false);
    editor.commit();
}

//...

public void testC_OpenLoginActivityIfUserIsNotLoggedIn() {
    ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
    Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);

    assertNotNull(nextActivity);
    nextActivity.finish();

    SharedPreferences.Editor editor = mLoginPrefs.edit();
            // Login the user so we can continue the tests
    editor.putBoolean("logged_in", true);
    editor.commit();
}
公共类MainActivityTest扩展ActivityInstrumentationTestCase2{
专用静态最终整数时间=5000;/*毫秒*/
私人活动和不活动;
私用仪器;
私有共享引用mLoginPrefs;
公共维护活动测试(){
超级(MainActivity.class);
}
受保护的void setUp()引发异常{
super.setUp();
setActivityInitialTouchMode(假);
mMainActivity=getActivity();
Minstruturement=getInstrumentation();
mLoginPrefs=mInstrumentation.getTargetContext().getSharedReferences(LoginActivity.PREFS\u NAME,Context.MODE\u PRIVATE);
SharedReferences.Editor=mLoginPrefs.edit();
//用户未登录,因此应重定向到LoginActivity
编辑器.putBoolean(“登录”,false);
commit();
}
//...
public void testC_OpenLoginActivityIfUserIsNotLoggedIn(){
ActivityMonitor monitor=mInstrumentation.addMonitor(LoginActivity.class.getName(),null,false);
Activity nextActivity=分钟执行。waitForMonitorWithTimeout(监视器,超时);
assertNotNull(nextActivity);
nextActivity.finish();
SharedReferences.Editor=mLoginPrefs.edit();
//登录用户以便我们可以继续测试
编辑器.putBoolean(“已登录”,true);
commit();
}
但这不起作用,LoginActivity打开,但waitForMonitorWithTimeout从未返回,因此我被LoginActivity卡住了(我需要返回MainActivity进行其他测试)

类似于此的代码适用于按钮单击,但此活动不会通过任何单击加载,因此我认为可能没有时间让监视器工作

我只需要一种获取实际活动的方法,这样我就可以进行断言并使其完成以继续我的测试


还有一件事:如果可能的话,我更喜欢不使用Robotium的方法。

您的思路是正确的。您需要调用的方法是:

monitor.waitForActivityWithTimeout(TIME_OUT);
而不是

mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);

为了解决您的问题,首先来看两种最重要的测试方法:

Instrumentation#addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean)
Instrumentation.ActivityMonitor#waitForActivity()
根据Android API参考:

添加监视器 添加一个新的Instrumentation.ActivityMonitor,每当启动一个活动时,都会检查该监视器。。该监视器是在任何现有监视器之后添加的;只有当现有监视器都无法处理该意图时,才会命中该监视器

等待活动 阻止,直到创建与该监视器匹配的活动,并返回结果活动


现在让我们更清楚一点

addMonitor应始终在启动预期活动之前调用,不要太迟

waitForActivity应仅在启动预期活动后调用,不要太早,因为它会阻塞


回到您的代码:

你把他们两个都叫在一起,其间没有任何神奇的事情发生。所以,要么对addMonitor来说太迟,要么对waitForActivity来说太早

ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
Activity nextActivity = mInstrumentation.waitForMonitorWithTimeout(monitor, TIME_OUT);
如果调用waitForActivity为时过早,它将阻塞并失败,直到超时(因为预期的活动尚未命中),并且您将永远看不到预期的活动正在启动

如果调用addMonitor为时已晚,则监视将在启动预期活动后启动,并且此后不会再次启动预期活动,因此waitForActivity将因未命中监视器而被阻止

因此,这两种情况之间的差异是是否启动了预期的活动。对于您的情况,我认为现在调用addMonitor已经太迟了

解决方案非常简单:只需在您的登录活动开始之前将addMonitor移动到足够早的位置,或者将其移动到设置方法,如下所示:

mInstrumentation = getInstrumentation();
ActivityMonitor monitor = mInstrumentation.addMonitor(LoginActivity.class.getName(), null, false);
顺便说一句,对于你的情况,有没有超时并不重要

不要忘记在不再需要
监视器后将其卸下,例如:

@Override
protected void tearDown() throws Exception {
    mInstrumentation.removeMonitor(monitor);
    super.tearDown();
}

根据API参考资料,他所做的是正确的:waitForMonitorWithTimeout(Instrumentation.ActivityMonitor,long timeOut)和Kotlin,类名称过去到
addMonitor()
应该是什么样的?我尝试了
“com.蝗虫板.sdktestapp.MapActivity”
MapActivity::class.java.name.toString()
MapActivity::class.java.canonicalName.toString()
,以及其他,但
WaitFormMonitorWithTimeout()
返回了
null
。此解决方案对我的Kotlin应用程序有效,谢谢。出于某种原因,
.getActivitiesInStage(已恢复)
只给了我一个空集合。这只适用于检测同一包中的活动吗?
public static Activity getCurrentActivity() {
    final Activity[] currentActivity = {null};
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance()
                    .getActivitiesInStage(RESUMED);
            if (resumedActivities.iterator().hasNext()) {
                currentActivity[0] = (Activity) resumedActivities.iterator().next();
            }
        }
    });
    return currentActivity[0];
}