Android(安卓)5.0+ 系统 WebView 可见性及合成器内存管理
16lz
2021-01-26
| WebView Ancestor View 不可见/可见 | WebView 不可见/可见 | WebView Window 不可见/可见 | WebView Detach/Attach | WebView Pause/Resume |
系统 WebView (Android 5.0+) | 除了 WebView 不再参与 Android UI 的绘制外没有影响 | 除了 WebView 不再参与 Android UI 的绘制外没有影响 | 更新 WebView 可见性状态,影响网页更新和 WebView 的绘制 释放部分合成器内存(参考第3条) | 更新 WebView 可见性状态,影响网页更新和 WebView 的绘制 释放大部分合成器内存(参考第4条) | 更新 WebView 可见性状态,影响网页更新和 WebView 的绘制 释放部分合成器内存 (参考第3条) |
- WebView 可见性是由下面几个因素决定的(参考附注的代码),这个可见性的逻辑跟 WebView 作为一个 Android View 是否可见完全不同,它主要影响内核的更新和在应用窗口上的绘制:
- 如果 WebView Paused,则不可见;
- 如果 WebView 从来没有 Attach 过,则可见;
- 如果 WebView Attach 后 Detach,则不可见;
- 如果 WebView 当前 Attached,取决于 Window 是否可见;
- 如果 WebView 被认为不可见,子合成器的 MainFrame 停止发送,网页内容无法更新,ImplFrame 无法绘制(只能软件渲染方式进行截图),如果 WebView 还在UI界面上可见,父合成器会重复绘制最后一帧;
- 如果 WebView 被认为不可见,会释放部分合成器内存:
- 子合成器会释放部分 Resources(纹理) 和子合成器 Context 部分资源(Command Buffer 内部所使用的缓存),发送给父合成器的 Resources 不会被释放;
- 释放大部分合成器内存:
- 子合成器会释放所有 Resources(纹理) 和子合成器 Context 大部分资源(Command Buffer 内部所使用的缓存);
- 父合成器会整个销毁,包括父合成器的 Context;
- 原生代码存在少部分 Resources 残留无法释放的问题,因为父合成器的销毁在后,并且父合成器销毁后,占用的 Resources 没有返回给子合成器,导致子合成器无法释放这些已经不再使用的 Resources(WebView 重新 Attach 或者 Destroy 后这部分 Resources 会释放);
附注:
- WebView Window 不可见/可见通常发生在应用切换到后台/前台,或者当前窗口被另外一个窗口覆盖/恢复;
- WebView 判定是否可见的代码如下:
bool BrowserViewRenderer::IsClientVisible() const { // When WebView is not paused, we declare it visible even before it is // attached to window to allow for background operations. If it ever gets // attached though, the WebView is visible as long as it is attached // to a window and the window is visible. return is_paused_ ? false : !was_attached_ || (attached_to_window_ && window_visible_); } |
更多相关文章
- Android(安卓)电源管理 -- wakelock机制
- Android(安卓)NDK(六):JNI局部引用和全局引用
- 在android开发中应该如何管理内存或者是在开发过程中应该注意哪
- 下拉刷新和加载更多
- Android代码内存优化建议-Android官方篇
- 尽量避免android oom
- android释放内存提示
- Android面试系列文章2018之内存管理篇
- Android(安卓)RecyclerView下拉刷新和上拉加载更多