【已解决】 Presentation 被中断 dismiss
   做个双屏异显,发现中断问题
1.系统拥有熄屏(安卓板厂商提供的,估计是直接切断背光源)功能,问题发生在熄屏恢复之后(概率发生),且重新熄屏后概率恢复,重启后必定恢复。
2.显示错误为Presentation is being dismissed because the display metrics have changed since it was created.
3.activity中设置onConfigurationChangeListener,发生错误时并没有进入。
4.发生dismiss后尝试重新设置所有参数,在show之后观察到onCreate后onStart前依然出现Presentation is being dismissed because the display metrics have changed since it was created.
5.没有更改过任何屏幕参数,注意到错误发生在Presentation类源码中的这个判断,返回了false导致触发cancel()->dismiss()
private boolean isConfigurationStillValid() {
    DisplayMetrics dm = new DisplayMetrics();
    mDisplay.getMetrics(dm);
    return dm.equalsPhysical(getResources().getDisplayMetrics());
}
源码如下
private void initDifferentDisplay() {
    //双屏显示
    Holder<Boolean> isCancel = new Holder<>(false);
    difScreenScheduler = new Scheduler.Builder(1000, it -> {
        //没有副屏或者副屏失效,不显示
        DisplayManager mDisplayManager;//屏幕管理类
        mDisplayManager = (DisplayManager)MainActivity.this.getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays;//屏幕数组
        displays = mDisplayManager.getDisplays(); //得到显示器数组
        if (displays.length < 2 || !displays[1].isValid()) {
            if (mPresentation != null && mPresentation.isShowing()) {
                mPresentation.dismiss();
                Log.d(TAG_PRESENTATION, "no second screen or invalid");
            }
            mPresentation = null;
            return;
        }
        try {
            //Presentation不为空,更新副屏内容
            if (mPresentation != null) {
                if (mPresentation.isShowing()) {
                    //展示副屏中,刷新数据
                    mPresentation.secondScreenRefresh();
                }
                else {
                    Log.d(TAG_PRESENTATION, "presentation not show,need to be show");
                    if (isCancel.get()) {
                        Log.d(TAG_PRESENTATION, "Configuration changed,need to new a presentation");
                        initPresentation(displays[1], isCancel);
                        isCancel.set(false);
                    } else {
                        mPresentation.show();
                    }
                }
            }
            //副屏可用,presentation为空,(一开始未接设备,后面接通)
            if (mPresentation == null && displays[1].isValid()) {
                Log.d(TAG_PRESENTATION, "Second screen is valid,but presentation is null,init to show");
                initPresentation(displays[1], isCancel);
            }
        } catch (RuntimeException e) {
            mPresentation = null;
            Log.e(TAG_PRESENTATION, "Presentation exception: ", e);
        }
    }).build();
    difScreenScheduler.start();
}
private void initPresentation(Display display, Holder<Boolean> isCancel) {
    if (mPresentation != null) {
        mPresentation = null;
    }
    mPresentation = new SecondaryDisplay
            (this, display);//displays[1]是副屏
    mPresentation.setOnCancelListener(dialog -> {
        //屏幕配置更改,包括熄屏后结束的
        Log.d(TAG_PRESENTATION, "Presentation canceled due to dismiss or display configuration");
        isCancel.set(true);
    });
    if (mPresentation.getWindow() != null)
        mPresentation.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    Log.d(TAG_PRESENTATION, "Presentation: init show");
    mPresentation.show();
}
     
已经解决,Presentation源码是通过下面来判断屏幕参数是否改变的
由于不知名原因(可能是安卓板厂商提供的熄屏api偷偷修改了参数?)
private boolean isConfigurationStillValid() { DisplayMetrics dm = new DisplayMetrics(); mDisplay.getMetrics(dm); return dm.equalsPhysical(getResources().getDisplayMetrics()); }所以,只需要在Presentation准备show时,判断是否更改并改回副屏原本的参数即可
private void cloneDisplayMetrics() { DisplayMetrics dm = new DisplayMetrics(); getDisplay().getMetrics(dm); getResources().getDisplayMetrics().setTo(dm); }目前感觉是AutoSize框架改变了DisplayMetrics的问题,可能在创建Presentation onCreate之后恰好发生了适配,导致屏幕参数改变引发的问题,目前尚未找到解决方法
Presentation 里加视频图片混合的轮播图,你有试过吗/