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.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
import android.webkit.WebChromeClient
|
import android.webkit.WebChromeClient
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
@@ -29,12 +31,36 @@ class WebViewManager(private val context: Context) {
|
|||||||
this.callback = callback
|
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 的简洁实现
|
* 初始化 WebView - 参考 zuiqiang 的简洁实现
|
||||||
*/
|
*/
|
||||||
fun initWebView(webView: WebView) {
|
fun initWebView(webView: WebView) {
|
||||||
this.webView = webView
|
this.webView = webView
|
||||||
|
|
||||||
|
// 🔧 GPU渲染兼容性:使用软件渲染层避免EGL fence错误
|
||||||
|
// 当WebView与MediaProjection同时使用GPU时,EGL fence对象创建会失败
|
||||||
|
// 使用LAYER_TYPE_SOFTWARE可以避免GPU资源竞争,消除chromium EGL错误
|
||||||
|
configureRenderLayer(webView)
|
||||||
|
|
||||||
// 🚀 极简配置 - 参考 zuiqiang 项目
|
// 🚀 极简配置 - 参考 zuiqiang 项目
|
||||||
val settings = webView.settings
|
val settings = webView.settings
|
||||||
settings.javaScriptEnabled = true
|
settings.javaScriptEnabled = true
|
||||||
@@ -54,7 +80,7 @@ class WebViewManager(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) {
|
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
|
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 的简洁实现
|
* JavaScript 接口 - 参考 zuiqiang 的简洁实现
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user