Force instrumented activity 运行 in multi-window 模式

Force instrumented activity run in multi-window mode

如您所知,android 在 android N 中提供了 Multi-Window support mode。我们的应用程序具有多 window 支持。
但是如何测试呢?如何在该模式下强制测试 运行 应用程序?我没有在 Instrumentation class 或文档中的其他任何地方建立任何此类方法。也许 Espresso?

在某种程度上是可能的

来自Launch New Activities in Multi-Window Mode:

When you launch a new activity, you can hint to the system that the new activity should be displayed adjacent to the current one, if possible. To do this, use the intent flag FLAG_ACTIVITY_LAUNCH_ADJACENT.

来自 Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT 的文档:

This flag is only used in split-screen multi-window mode. The new activity will be displayed adjacent to the one launching it. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK. Also, setting FLAG_ACTIVITY_MULTIPLE_TASK is required if you want a new instance of an existing activity to be created.

如图here如何启动activity正在测试:

@Test
public void customIntentToStartActivity() {
    Intent intent = new Intent(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT) 
                | Intent.FLAG_ACTIVITY_NEW_TASK);
    mActivity = mActivityRule.launchActivity(intent);
}

注意,这是我根据文档猜测的,没试过。虽然,在我看来你必须先启动 "fake" Activity,然后从那里启动测试 activity 多 window模式,因为"The new activity will be displayed adjacent to the one launching it",所以应该有另一个activity用指定的Intent标志启动它。

不幸的是 requires an app which has been loaded in multi-window mode previously, so I want to provide own solution. At the answer 我找到了如何以编程方式进入 multi-window 模式。使用它我构建了完整的解决方案:

    UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
    //enter multi-window mode
    uiAutomation.performGlobalAction(AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
    //wait for completion, unfortunately waitForIdle doesn't applicable here
    Thread.sleep(1000);
    //simulate selection of our activity
    MotionEvent motionDown = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN,
            150, 200, 0);
    motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN);
    uiAutomation.injectInputEvent(motionDown, true);
    motionDown.recycle();
    MotionEvent motionUp = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_UP,
            150, 200, 0);
    motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN);
    uiAutomation.injectInputEvent(motionUp, true);
    motionUp.recycle();
    //perform test actions below

如您所见,有两种解决方法:

  1. 不能用uiAutomation.waitForIdle等待进入多模式完成
  2. 我还没有找到 select 任务管理器中的应用程序请求关注我们的 activity 的方法。所以我只是在 activity.
  3. 的可能位置上执行一些触摸事件

实施后,您将能够像往常一样使用 Espresso 等来测试 activity。