Skip to content

Commit 86e84ae

Browse files
committed
refactor(android): streamline WebViewClient implementation and enhance file request handling
1 parent 54b84dc commit 86e84ae

2 files changed

Lines changed: 69 additions & 129 deletions

File tree

android/dimina/src/main/kotlin/com/didi/dimina/ui/view/DiminaWebView.kt

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -102,42 +102,7 @@ private fun createWebView(context: Context, onPageLoadFinished: () -> Unit): Web
102102
}
103103

104104
// Configure WebViewClient with file interceptor
105-
webViewClient = object : WebViewClient() {
106-
override fun onPageFinished(view: WebView, url: String) {
107-
super.onPageFinished(view, url)
108-
LogUtils.d(TAG, "WebView page finished loading: $url")
109-
if (url.contains("pageFrame.html")) {
110-
onPageLoadFinished()
111-
}
112-
}
113-
114-
override fun shouldInterceptRequest(
115-
view: WebView,
116-
request: WebResourceRequest
117-
): WebResourceResponse? {
118-
val url = request.url.toString()
119-
val context = view.context
120-
121-
if (url.startsWith(FILE_PROTOCOL)) {
122-
try {
123-
val localFile = getFilesFile(context, url.substring(FILE_PROTOCOL.length))
124-
if (localFile.exists()) {
125-
LogUtils.d(TAG, "Loading file from local: $url")
126-
val mimeType = MimeTypeMap.getSingleton()
127-
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
128-
?: "text/html" // Fallback MIME type
129-
return WebResourceResponse(mimeType, "UTF-8", FileInputStream(localFile))
130-
} else {
131-
LogUtils.e(TAG, "intercepting file: $url is not existed")
132-
}
133-
} catch (e: Exception) {
134-
LogUtils.e(TAG, "Error intercepting file: $url", e)
135-
}
136-
}
137-
// Fall back to default handling for other resources
138-
return super.shouldInterceptRequest(view, request)
139-
}
140-
}
105+
webViewClient = createWebViewClientWithInterceptor { onPageLoadFinished() }
141106
}
142107
}
143108

@@ -171,27 +136,6 @@ fun WebView.postMessage(msg: String, callback: ((String?) -> Unit)? = null) {
171136
}
172137

173138

174-
/**
175-
* 根据给定的URL获取文件对象
176-
* 此函数用于区分jsapp和jssdk类型的URL,并返回相应的文件对象
177-
*
178-
* @param context 上下文对象,用于访问应用程序的文件目录
179-
* @param url 需要解析的URL,用于确定文件路径
180-
* @return 返回一个File对象,表示解析后的文件路径
181-
*/
182-
private fun getFilesFile(context: Context, url: String): File {
183-
val filesDir = context.filesDir
184-
val appIdRegex = "(wx|dd)[0-9a-zA-Z]{16}".toRegex()
185-
val matchResult = appIdRegex.find(url)
186-
return if (matchResult != null) {
187-
// jsapp url,使用 appId 并构造路径
188-
File(filesDir, "jsapp/$url")
189-
} else {
190-
// jssdk url,使用版本号构造路径
191-
File(filesDir, "jssdk/${VersionUtils.getJSVersion()}/main/$url")
192-
}
193-
}
194-
195139
/**
196140
* JavaScript interface for DiminaRenderBridge
197141
* This class provides the native implementation of the DiminaRenderBridge

android/dimina/src/main/kotlin/com/didi/dimina/ui/view/WebViewCacheManager.kt

Lines changed: 68 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -276,41 +276,7 @@ object WebViewCacheManager : ComponentCallbacks2 {
276276
webView.clearCache(true)
277277

278278
// 重新设置WebViewClient
279-
webView.webViewClient = object : WebViewClient() {
280-
override fun onPageFinished(view: WebView, url: String) {
281-
super.onPageFinished(view, url)
282-
LogUtils.d(TAG, "Cached WebView page finished loading: $url")
283-
if (url.contains("pageFrame.html")) {
284-
onPageLoadFinished()
285-
}
286-
}
287-
288-
override fun shouldInterceptRequest(
289-
view: WebView,
290-
request: WebResourceRequest
291-
): WebResourceResponse? {
292-
val url = request.url.toString()
293-
val context = view.context
294-
295-
if (url.startsWith(FILE_PROTOCOL)) {
296-
try {
297-
val localFile = getFilesFile(context, url.substring(FILE_PROTOCOL.length))
298-
if (localFile.exists()) {
299-
LogUtils.d(TAG, "Loading file from local: $url")
300-
val mimeType = MimeTypeMap.getSingleton()
301-
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
302-
?: "text/html"
303-
return WebResourceResponse(mimeType, "UTF-8", FileInputStream(localFile))
304-
} else {
305-
LogUtils.e(TAG, "intercepting file: $url is not existed")
306-
}
307-
} catch (e: Exception) {
308-
LogUtils.e(TAG, "Error intercepting file: $url", e)
309-
}
310-
}
311-
return super.shouldInterceptRequest(view, request)
312-
}
313-
}
279+
webView.webViewClient = createWebViewClientWithInterceptor { onPageLoadFinished() }
314280

315281
} catch (e: Exception) {
316282
LogUtils.e(TAG, "Failed to reset WebView", e)
@@ -507,6 +473,9 @@ object WebViewCacheManager : ComponentCallbacks2 {
507473
}
508474
}
509475

476+
// 文件级别的TAG常量,用于日志记录
477+
private const val WEBVIEW_TAG = "WebViewInterceptor"
478+
510479
/**
511480
* 根据给定的URL获取文件对象
512481
* 此函数用于区分jsapp和jssdk类型的URL,并返回相应的文件对象
@@ -515,7 +484,7 @@ object WebViewCacheManager : ComponentCallbacks2 {
515484
* @param url 需要解析的URL,用于确定文件路径
516485
* @return 返回一个File对象,表示解析后的文件路径
517486
*/
518-
private fun getFilesFile(context: Context, url: String): File {
487+
internal fun getFilesFile(context: Context, url: String): File {
519488
val filesDir = context.filesDir
520489
val appIdRegex = "(wx|dd)[0-9a-zA-Z]{16}".toRegex()
521490
val matchResult = appIdRegex.find(url)
@@ -528,6 +497,68 @@ private fun getFilesFile(context: Context, url: String): File {
528497
}
529498
}
530499

500+
/**
501+
* 创建统一的文件拦截处理器
502+
* 用于拦截WebView的文件协议请求,从本地文件系统加载资源
503+
*
504+
* @param onPageFinished 页面加载完成的回调
505+
* @return WebViewClient实例
506+
*/
507+
internal fun createWebViewClientWithInterceptor(
508+
onPageFinished: (String) -> Unit = {}
509+
): WebViewClient {
510+
return object : WebViewClient() {
511+
override fun onPageFinished(view: WebView, url: String) {
512+
super.onPageFinished(view, url)
513+
LogUtils.d(WEBVIEW_TAG, "WebView page finished loading: $url")
514+
if (url.contains("pageFrame.html")) {
515+
onPageFinished(url)
516+
}
517+
}
518+
519+
override fun shouldInterceptRequest(
520+
view: WebView,
521+
request: WebResourceRequest
522+
): WebResourceResponse? {
523+
return handleFileInterceptRequest(view.context, request)
524+
}
525+
}
526+
}
527+
528+
/**
529+
* 统一处理文件拦截请求的逻辑
530+
* 拦截file://协议的请求,从本地文件系统加载资源
531+
*
532+
* @param context 上下文对象
533+
* @param request WebView资源请求
534+
* @return 如果是文件协议请求且文件存在,返回WebResourceResponse;否则返回null
535+
*/
536+
internal fun handleFileInterceptRequest(
537+
context: Context,
538+
request: WebResourceRequest
539+
): WebResourceResponse? {
540+
val url = request.url.toString()
541+
542+
if (url.startsWith(FILE_PROTOCOL)) {
543+
try {
544+
val localFile = getFilesFile(context, url.substring(FILE_PROTOCOL.length))
545+
if (localFile.exists()) {
546+
LogUtils.d(WEBVIEW_TAG, "Loading file from local: $url")
547+
val mimeType = MimeTypeMap.getSingleton()
548+
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
549+
?: "text/html" // Fallback MIME type
550+
return WebResourceResponse(mimeType, "UTF-8", FileInputStream(localFile))
551+
} else {
552+
LogUtils.e(WEBVIEW_TAG, "intercepting file: $url is not existed")
553+
}
554+
} catch (e: Exception) {
555+
LogUtils.e(WEBVIEW_TAG, "Error intercepting file: $url", e)
556+
}
557+
}
558+
559+
return null
560+
}
561+
531562
@SuppressLint("SetJavaScriptEnabled")
532563
private fun createWebView(context: Context, onPageLoadFinished: () -> Unit): WebView {
533564
return WebView(context).apply {
@@ -549,42 +580,7 @@ private fun createWebView(context: Context, onPageLoadFinished: () -> Unit): Web
549580
}
550581

551582
// Configure WebViewClient with file interceptor
552-
webViewClient = object : WebViewClient() {
553-
override fun onPageFinished(view: WebView, url: String) {
554-
super.onPageFinished(view, url)
555-
LogUtils.d("WebViewCacheManager", "WebView page finished loading: $url")
556-
if (url.contains("pageFrame.html")) {
557-
onPageLoadFinished()
558-
}
559-
}
560-
561-
override fun shouldInterceptRequest(
562-
view: WebView,
563-
request: WebResourceRequest
564-
): WebResourceResponse? {
565-
val url = request.url.toString()
566-
val context = view.context
567-
568-
if (url.startsWith(FILE_PROTOCOL)) {
569-
try {
570-
val localFile = getFilesFile(context, url.substring(FILE_PROTOCOL.length))
571-
if (localFile.exists()) {
572-
LogUtils.d("WebViewCacheManager", "Loading file from local: $url")
573-
val mimeType = MimeTypeMap.getSingleton()
574-
.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
575-
?: "text/html" // Fallback MIME type
576-
return WebResourceResponse(mimeType, "UTF-8", FileInputStream(localFile))
577-
} else {
578-
LogUtils.e("WebViewCacheManager", "intercepting file: $url is not existed")
579-
}
580-
} catch (e: Exception) {
581-
LogUtils.e("WebViewCacheManager", "Error intercepting file: $url", e)
582-
}
583-
}
584-
// Fall back to default handling for other resources
585-
return super.shouldInterceptRequest(view, request)
586-
}
587-
}
583+
webViewClient = createWebViewClientWithInterceptor { onPageLoadFinished() }
588584
}
589585
}
590586

0 commit comments

Comments
 (0)