Android 5.0+ 系统 WebView 可见性及合成器内存管理



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条)


  1. WebView 可见性是由下面几个因素决定的(参考附注的代码),这个可见性的逻辑跟 WebView 作为一个 Android View 是否可见完全不同,它主要影响内核的更新和在应用窗口上的绘制
    1. 如果 WebView Paused,则不可见;
    2. 如果 WebView 从来没有 Attach 过,则可见;
    3. 如果 WebView Attach 后 Detach,则不可见;
    4. 如果 WebView 当前 Attached,取决于 Window 是否可见;
  2. 如果 WebView 被认为不可见,子合成器的 MainFrame 停止发送,网页内容无法更新,ImplFrame 无法绘制(只能软件渲染方式进行截图),如果 WebView 还在UI界面上可见,父合成器会重复绘制最后一帧;
  3. 如果 WebView 被认为不可见,会释放部分合成器内存:
    1. 子合成器会释放部分 Resources(纹理) 和子合成器 Context 部分资源(Command Buffer 内部所使用的缓存),发送给父合成器的 Resources 不会被释放;
  4. 释放大部分合成器内存:
    1. 子合成器会释放所有 Resources(纹理) 和子合成器 Context 大部分资源(Command Buffer 内部所使用的缓存);
    2. 父合成器会整个销毁,包括父合成器的 Context;
    3. 原生代码存在少部分 Resources 残留无法释放的问题,因为父合成器的销毁在后,并且父合成器销毁后,占用的 Resources 没有返回给子合成器,导致子合成器无法释放这些已经不再使用的 Resources(WebView 重新 Attach 或者 Destroy 后这部分 Resources 会释放)


综上可见,对于原生 WebView,如果需要尽量释放更多内存,需要 Detach WebView,如果需要减少后台 WebView 的 CPU 占用,需要 Pause 或者 Detach WebView。

附注:
  1. WebView Window 不可见/可见通常发生在应用切换到后台/前台,或者当前窗口被另外一个窗口覆盖/恢复;
  2. 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_);
}


你可能感兴趣的:(浏览器,Chrome,Android)