【已解决】 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偷偷修改了参数?)
所以,只需要在Presentation准备show时,判断是否更改并改回副屏原本的参数即可
目前感觉是AutoSize框架改变了DisplayMetrics的问题,可能在创建Presentation onCreate之后恰好发生了适配,导致屏幕参数改变引发的问题,目前尚未找到解决方法
Presentation 里加视频图片混合的轮播图,你有试过吗/