fix: 修复WebView EGL fence GPU同步错误
- WebView初始化时切换到软件渲染层(LAYER_TYPE_SOFTWARE),避免与MediaProjection竞争GPU EGL资源 - 添加configureRenderLayer方法,解决chromium egl_fence_utils.cc错误 - 补充onReceivedError日志记录,替代静默处理 - 新增destroy方法确保WebView销毁时正确释放GPU和渲染资源 - 添加必要的import(Build, View)
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.webkit.WebChromeClient
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
@@ -29,12 +31,36 @@ class WebViewManager(private val context: Context) {
|
||||
this.callback = callback
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 配置WebView渲染层,避免EGL fence GPU同步错误
|
||||
*
|
||||
* 问题根因:WebView(Chromium)硬件加速渲染与MediaProjection的VirtualDisplay
|
||||
* 同时竞争GPU EGL资源,导致eglCreateSyncKHR返回EGL_NO_SYNC,
|
||||
* 触发 "Unable to get a gpu fence object" 错误。
|
||||
*
|
||||
* 解决方案:将WebView切换到软件渲染层,让GPU资源专供MediaProjection使用
|
||||
*/
|
||||
private fun configureRenderLayer(webView: WebView) {
|
||||
try {
|
||||
// 软件渲染层避免WebView与MediaProjection的GPU资源竞争
|
||||
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
|
||||
Log.i(TAG, "🔧 WebView已切换到软件渲染层,避免EGL fence错误")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 配置WebView渲染层失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 WebView - 参考 zuiqiang 的简洁实现
|
||||
*/
|
||||
fun initWebView(webView: WebView) {
|
||||
this.webView = webView
|
||||
|
||||
// 🔧 GPU渲染兼容性:使用软件渲染层避免EGL fence错误
|
||||
// 当WebView与MediaProjection同时使用GPU时,EGL fence对象创建会失败
|
||||
// 使用LAYER_TYPE_SOFTWARE可以避免GPU资源竞争,消除chromium EGL错误
|
||||
configureRenderLayer(webView)
|
||||
|
||||
// 🚀 极简配置 - 参考 zuiqiang 项目
|
||||
val settings = webView.settings
|
||||
settings.javaScriptEnabled = true
|
||||
@@ -54,7 +80,7 @@ class WebViewManager(private val context: Context) {
|
||||
}
|
||||
|
||||
override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) {
|
||||
// 静默处理错误
|
||||
Log.w(TAG, "⚠️ WebView加载错误: code=$errorCode, desc=$description, url=$failingUrl")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +222,27 @@ class WebViewManager(private val context: Context) {
|
||||
return webView?.visibility == android.view.View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 销毁WebView,释放GPU和渲染资源
|
||||
* 必须在Activity/Fragment销毁时调用,防止GPU资源泄漏
|
||||
*/
|
||||
fun destroy() {
|
||||
try {
|
||||
webView?.let { wv ->
|
||||
wv.stopLoading()
|
||||
wv.loadUrl("about:blank")
|
||||
wv.clearHistory()
|
||||
wv.removeAllViews()
|
||||
wv.destroy()
|
||||
Log.i(TAG, "✅ WebView已销毁,GPU资源已释放")
|
||||
}
|
||||
webView = null
|
||||
callback = null
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "❌ 销毁WebView失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JavaScript 接口 - 参考 zuiqiang 的简洁实现
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user