在android webview中下载超过100MB的blob文件是否有任何大小限制?

Have any size restriction on download a blob file above 100MB in android webview?

提问人:Mimo Saha 提问时间:10/5/2023 最后编辑:Mimo Saha 更新时间:10/5/2023 访问量:68

问:

您好,我正在分享我在 Webview 和 JavaScriptInterface 中使用的代码库。我无法使用我的代码库下载大文件。当文件大小约为 50MB 时,我的代码库正在工作。

如果您有解决方案,请分享

接下来的部分是 xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <WebView
        android:id="@+id/browser"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.appcompat.widget.LinearLayoutCompat>

我用于配置 webview 设置的以下代码。我得到像(blob:https//..../a8322jh-.....)这样的blob URL。所以用了 JavaScriptInterface

        browser.clearCache(true)
        browser.clearFormData()
        browser.clearHistory()
        browser.clearMatches()
        browser.clearSslPreferences()
        browser.removeJavascriptInterface("Abcdabcd")

        browser.webViewClient = object : WebViewClient() {

            override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
                Log.v("BrowserExample", "URL - " + request?.url?.toString())
                return super.shouldInterceptRequest(view, request)
            }

            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                Log.v("BrowserExample", "Loading URL - " + request?.url?.toString())
                return super.shouldOverrideUrlLoading(view, request)
            }

            override fun onPageFinished(view: WebView, url: String) {

            }

            override fun onReceivedError(
                view: WebView?,
                request: WebResourceRequest?,
                error: WebResourceError?
            ) {
                Log.e("BrowserExample", "ERROR1 - ${error?.description}")
                super.onReceivedError(view, request, error)
            }

            override fun onReceivedHttpError(
                view: WebView?,
                request: WebResourceRequest?,
                errorResponse: WebResourceResponse?
            ) {
                Log.e("BrowserExample", "ERROR2 - ${errorResponse?.statusCode}")
                super.onReceivedHttpError(view, request, errorResponse)
            }

            override fun onReceivedSslError(
                view: WebView?,
                handler: SslErrorHandler?,
                error: SslError?
            ) {
                Log.e("BrowserExample", "onReceivedSslError")
                super.onReceivedSslError(view, handler, error)
            }

            override fun onReceivedLoginRequest(
                view: WebView?, realm: String?, account: String?, args: String?) {
                Log.v("BrowserExample", "onReceivedLoginRequest")
                super.onReceivedLoginRequest(view, realm, account, args)
            }
        }

        browser.webChromeClient = object : WebChromeClient() {
            override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
                Log.v("BrowserExample", "console - ${consoleMessage?.message()}")
                return super.onConsoleMessage(consoleMessage)
            }

            override fun onPermissionRequest(request: PermissionRequest) {
                request.grant(request.resources)
            }
        }

        browser.settings.javaScriptEnabled = true
        browser.settings.domStorageEnabled = true

        browser.settings.setAppCachePath(applicationContext.cacheDir.absolutePath)
        browser.settings.cacheMode = WebSettings.LOAD_DEFAULT
        browser.settings.databaseEnabled = true

        browser.settings.allowFileAccess = true
        browser.settings.allowFileAccessFromFileURLs = true
        browser.settings.allowContentAccess = true

        browser.settings.mediaPlaybackRequiresUserGesture = false
        
        browser.settings.userAgentString = "Mozilla/5.0 (Linux; U; Android 10; SM-G960F Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.50 Mobile Safari/537.36 OPR/60.0.2254.59405"

        browser.addJavascriptInterface(
            JavaScriptInterface(applicationContext), "Abcdabcd")

        browser.setDownloadListener { url, userAgent, contentDisposition, mimeType, contentLength ->
            browser.loadUrl(JavaScriptInterface.getBase64StringFromBlobUrl(url))
        }

        browser.loadUrl(webUrl)

接下来的部分是 JavaScriptInterface

fun getBase64StringFromBlobUrl(blobUrl: String): String {
            return if (blobUrl.startsWith("blob")) {
                "javascript: var xhr = new XMLHttpRequest();" +
                        "console.log('Step - 1');" +
                        "xhr.open('GET', '" + blobUrl + "', true);" +
                        "console.log('Step - 2');" +
                        "xhr.timeout = 60000;" +
                        "console.log('Step - 3');" +
                        "xhr.setRequestHeader('Content-type','video/webm');" +
                        "console.log('Step - 4');" +
                        "xhr.onreadystatechange = function(){" +
                        "   console.log('Ready State Change 1: ' + this.readyState);" +
                        "   console.log('Ready State Change 2: ' + this.responseType);" +
                        "};" +
                        "xhr.responseType = 'blob';" +
                        "console.log('Step - 5');" +
                        "xhr.onload = function(e) {" +
                        "    console.log('Onload Called ' + this.status);" +
                        "    if (this.status == 200) {" +
                        "        var blobData = this.response;" +
                        "        var chunkSize = 1024 * 1024;" +
                        "        try {" +
                        "            var reader = new FileReader();" +
                        "            reader.readAsArrayBuffer(blobData);" +
                        "            reader.onload = function(ev) {" +
                        "                console.log('Reader Onload Called');" +
                        "                base64data = ev.target.result;" +
                        "                var totalChunks = Math.ceil(blobData.size / chunkSize);" +
                        "                console.log('Total chunk - ' + totalChunks);" +
                        "                Abcdabcd.createNewDownloadFile();" +
                        "                for (let i = 0; i < totalChunks; i++) {" +
                        "                    console.log('Processing Chunk No. - ' + i);" +
                        "                    var from = i * chunkSize;" +
                        "                    var to = from + chunkSize;" +
                        "                    var byteArray = new Uint8Array(base64data.slice(from, to));" +
                        "                    var isLast = (i + 1) == totalChunks;" +
                        "                    Abcdabcd.getBase64FromBlobData(byteArray, isLast);" +
                        "                 }" +
                        "             }" +
                        "          }" +
                        "          catch(err) {" +
                        "              console.log('error ' + err);" +
                        "          }" +
                        "     }" +
                        "};" +
                        "xhr.onerror = function() {" +
                        "    console.log('Request Error: ' + xhr.responseText);" +
                        "};" +
                        "console.log('Step - 6');" +
                        "xhr.send();";
            } else "javascript: console.log('It is not a Blob URL');"
        }

下载大约 100MB 时出错

Uncaught InvalidStateError: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'blob').

请检查上面的代码并分享错误是什么。 谢谢

javascript android kotlin webview 大文件

评论

0赞 blackapps 10/6/2023
什么是 blob url?
0赞 blackapps 10/6/2023
谁是 base64 编码?为什么?
0赞 blackapps 10/6/2023
谁是 base64 解码?解释应该发生什么以及为什么。
0赞 blackapps 10/6/2023
您正在下载哪种类型的文件?一旦它下载了,它应该会发生什么?

答: 暂无答案