Android双屏场景使用Presentation切换Activity时闪屏与内存泄漏问题求解
问题解决思路与实现方案
核心问题根因
你遇到的闪烁和内存泄漏问题本质来自两个原因:
- 现有逻辑中旧Presentation销毁和新Presentation加载存在时序差,副屏会在两个实例切换的间隙显示系统默认内容/前Activity残留
- 旧Presentation销毁时没有完全清除持有的旧Activity Context、View、回调等引用,被长生命周期对象持有后产生内存泄漏
方案1:最小改动优化现有逻辑
直接调整你现有setActivity方法的执行时序,等新Presentation完成首次绘制后再销毁旧实例,同时增加引用清理逻辑避免内存泄漏:
private void setActivity(Activity activity) { final MyPresentation oldPresentation = presentation; try { presentation = new MyPresentation(activity, getDisplay(activity), activity.getLocalClassName()); presentation.setCancelable(false); presentation.setCanceledOnTouchOutside(false); // 监听新Presentation的首次绘制完成事件 presentation.getWindow().getDecorView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // 新实例绘制完成后再销毁旧实例,消除切换间隙 if (oldPresentation != null && oldPresentation.isShowing()) { try { oldPresentation.dismiss(); // 手动清除旧实例所有持有引用,避免内存泄漏 oldPresentation.setContentView(null); oldPresentation.setOnDismissListener(null); oldPresentation.setOnCancelListener(null); } catch (Exception e) { e.printStackTrace(); } } // 移除监听器避免内存泄漏 presentation.getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); presentation.show(); } catch (Exception e) { e.printStackTrace(); // 异常场景恢复旧实例,避免副屏黑屏 presentation = oldPresentation; } }
额外注意:
- 持有
presentation变量的类不要用静态引用,如果是单例类要改用WeakReference持有Presentation实例 - 每个Activity的
onDestroy生命周期中,检查当前Presentation持有的Context是否为正在销毁的Activity,如果是要清空对应关联的业务回调
方案2:彻底消除切换闪烁的最优方案
使用全局专属透明Activity承载Presentation,完全避免实例重建:
- 新建一个无UI的透明Activity,启动模式设置为
singleInstance,专门作为Presentation的宿主Context,应用运行期间全程只初始化一次 - 所有业务Activity切换时都不销毁这个透明Activity,对应的Presentation也不需要重建,副屏不会出现任何切换间隙
- 应用退出时再销毁该透明Activity和对应的Presentation,完全不会产生内存泄漏
方案3:高版本系统无依赖方案
如果你的应用适配Android 8.0及以上系统,可以直接绕过Presentation实现副屏渲染:
- 申请
SYSTEM_ALERT_WINDOW悬浮窗权限,直接通过WindowManager把自定义View添加到副屏对应的Display上 - 该方式只需要用ApplicationContext即可实现,不需要依赖任何Activity实例,全程只需要创建一次副屏View,切换Activity完全无闪烁,也不会产生内存泄漏
内容的提问来源于stack exchange,提问作者Thibaut Goutel
相关产品推荐
相关产品推荐

