WebView 常见坑与性能优化清单
Top 10 坑
1. setJavaScriptEnabled 默认关闭
忘了开 → 现代网页全白屏,看起来像渲染失败。默认 false,记得显式开 s.setJavaScriptEnabled(true)。
2. Activity 销毁时没 destroy()
@Override
protected void onDestroy() {
webView.destroy(); // 必须!否则 WebView 进程泄漏
super.onDestroy();
}
WebView 是独立进程,Activity 销毁时如果不 destroy 它,渲染进程会一直活着,内存泄漏严重。
3. addJavascriptInterface 时机错误
必须在 loadUrl 之前注册,且只能注册一次——后续 loadUrl 不会触发重注册。
4. 忽略硬件加速副作用
WebView 默认开启硬件加速(Android 5.0+),但某些 GPU 机型上可能导致:
- 渲染花屏
- 视频播放异常
- Canvas 元素不显示
如果遇到,尝试:
// 全局禁用 WebView 硬件加速(Android 4.4+)
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
5. shouldOverrideUrlLoading 没有返回正确值
// 正确写法:返回 false 表示不拦截,让 WebView 自己加载
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
返回 true → WebView 不加载任何东西,需要你自己处理 URL(比如 Intent 跳浏览器)。
6. WebView 里弹 Dialog / Toast 崩溃
WebView 运行在渲染进程,Dialog 需要 Activity Context。不要直接从 addJavascriptInterface 的回调里弹 Dialog,用 runOnUiThread 切主线程。
7. Cookie 同步问题
CookieManager 和 WebView 的 Cookie 不是自动同步的。如果 App 用 HttpURLConnection 或 OkHttp 发请求,需要手动同步 Cookie:
CookieManager.getInstance().setCookie(url, cookieHeader);
8. Viewport meta 没设
网页的 <meta name="viewport" content="width=device-width"> 必须存在,WebView 默认不会自动按 View 宽度缩放。需要同时开:
s.setLoadWithOverviewMode(true);
s.setUseWideViewPort(true);
9. File 协议访问安全风险
setAllowFileAccess(true) 默认开启,但允许 file:// 访问会导致 WebView 加载本地文件——正式版必须关:
s.setAllowFileAccess(false);
s.setAllowFileAccessFromFileURLs(false);
s.setAllowUniversalAccessFromFileURLs(false);
10. 混合内容拦截
HTTPS 页面里加载 HTTP 资源(图片、JS、CSS)会被 WebView 拦截,表现为"图片不显示""功能失效"。建议:
// 测试时允许,正式发布前排查并修正
s.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
性能优化清单
| 项目 | 做法 |
|---|---|
| 减少 WebView 实例 | 每个 WebView 一个渲染进程,多个 WebView = 多个进程开销 |
| 复用 WebView | Fragment / Activity 切换时保留 WebView 实例,用 ViewStub 延迟加载 |
| 开启 WebKit Cache | s.setAppCacheEnabled(true) + s.setAppCachePath(...) |
| 硬件加速 | 确认设备 GPU 没问题后保持开启 |
| 减少 JS 执行 | 原生做计算密集型逻辑,JS 只做轻量交互 |
| 图片懒加载 | 网页端做,WebView 只是渲染 |
→ 返回 开发者入门首页