You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Travis测试的Android API至24后,Espresso测试持续报错求助

解决API 24升级后Espresso测试超时问题

先把你遇到的错误贴出来,方便其他开发者参考:

com.simplemobiletools.calculator.MainActivityTest > divisionByZeroTest[test(AVD) - 7.0] FAILED
java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not request layout for 10 seconds. If you specified a non default root matcher, it may be picking a root that never...

我之前把项目从API 22升级到24时,也碰到过一模一样的问题。主要是API 24开始Espresso对视图布局和焦点的检测逻辑更严格,再加上Android 7.0(API24)的系统行为变化,才导致了这个超时错误。给你几个亲测有效的解决方向:

1. 强制关闭系统动画

API 24之后,系统动画会严重干扰Espresso的视图状态检测——尤其是在Travis这类CI环境里,模拟器性能本来就有限,动画会让布局一直处于"请求重绘"的状态。你可以在Travis的测试脚本里添加这几条命令,在启动AVD后执行:

adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0

这会彻底关闭系统所有动画,让Espresso能准确检测到视图是否稳定。

2. 添加布局等待的IdlingResource

如果你的应用里有异步加载、自定义View或者复杂布局,API 24下Espresso可能没等到布局完全稳定就开始执行测试了。你可以自定义一个LayoutIdlingResource来监听视图树的布局请求,直到没有布局请求为止:

public class LayoutIdlingResource implements IdlingResource {
    private final View mRootView;
    private ResourceCallback mCallback;

    public LayoutIdlingResource(View rootView) {
        mRootView = rootView;
        mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (mCallback != null) {
                    mCallback.onTransitionToIdle();
                }
                // 移除监听避免重复回调
                mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
    }

    @Override
    public String getName() {
        return LayoutIdlingResource.class.getName();
    }

    @Override
    public boolean isIdleNow() {
        return !mRootView.isLayoutRequested();
    }

    @Override
    public void registerIdleTransitionCallback(ResourceCallback callback) {
        mCallback = callback;
    }
}

然后在测试中注册这个IdlingResource:

@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);

@Before
public void setUp() {
    View rootView = mActivityRule.getActivity().findViewById(android.R.id.content);
    IdlingRegistry.getInstance().register(new LayoutIdlingResource(rootView));
}

@After
public void tearDown() {
    IdlingRegistry.getInstance().unregisterAll();
}

3. 调整Travis的AVD配置

API 24的模拟器在Travis默认配置下可能性能不足,导致布局加载超时。你可以在.travis.yml里给模拟器分配更多内存,并且使用x86镜像(比ARM镜像快很多):

android:
  components:
    - tools
    - platform-tools
    - build-tools-30.0.2
    - android-24
    - sys-img-x86-android-24
  emulator:
    - emulator -avd test -no-window -no-audio -memory 2048 -accel on

另外,记得在启动模拟器后添加sleep 60之类的等待命令,让AVD完全启动后再开始测试。

4. 检查布局文件和自定义View的兼容性

API 22到24之间,一些布局属性的行为发生了变化,比如android:fitsSystemWindows在API 24后的处理逻辑不同,或者自定义View的onMeasure方法在新API下触发了无限重绘。你可以在本地用API 24的模拟器运行测试,打开开发者选项里的"显示布局边界"和"显示GPU过度绘制",检查是否有视图一直在重复布局。

我当时是靠关闭动画+调整AVD内存解决的问题,希望这些方法对你有用!

内容的提问来源于stack exchange,提问作者K. Vu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:34:35