Problems with Webview - Kotlin Android development


This webview keeps failing to load if the size of the loaded HTML file and it's assets are too large, however that behaviour is not consistent and happens seemingly randomly although is probably linked to how much background work the app is doing before the screen is launched.

I have tested reducing the size of one of the JS assets incrementally so I know for sure this is the the problem, although the fix is probably elsewhere as the asset is only 400KB. Reducing it to 200KB makes it load.

I have spent hours with different AI agents and am getting nowhere.

Here is the AndroidView, when it fails to load it logs onPageStarted but not onPagefinished:

AndroidView(

    factory = { ctx ->

        object : WebView(ctx) {
            override fun requestRectangleOnScreen(
                rect: Rect?,
                immediate: Boolean
            ): Boolean {
                // Block WebView/Quill from auto-scrolling parent Column on HTML load/focus
                return false
            }
        }.apply {

            Log.d("EDITOR", "WebView created")

            webView = this

            @Suppress("DEPRECATION")
            settings.apply {
                javaScriptEnabled = true
                allowFileAccess = true
                allowContentAccess = true
                allowFileAccessFromFileURLs = true
                allowUniversalAccessFromFileURLs = true
                domStorageEnabled = true
                databaseEnabled = true
                loadsImagesAutomatically = true
             }

            /*
             * JavaScript console logging.
             */

            webChromeClient = object : WebChromeClient() {

                override fun onConsoleMessage(
                    consoleMessage: ConsoleMessage?
                ): Boolean {

                    consoleMessage?.let {

                        Log.d(
                            "WebViewJS",
                            "${it.message()} -- " +
                                    "${it.sourceId()}:" +
                                    "${it.lineNumber()}"
                        )

                        AppLogger.log(
                            "WebViewJS: ${it.message()} -- " +
                                    "${it.sourceId()}:" +
                                    "${it.lineNumber()}"
                        )
                    }

                    return true
                }
            }

            webViewClient = object : WebViewClient() {

                override fun onPageStarted(
                    view: WebView?,
                    url: String?,
                    favicon: android.graphics.Bitmap?
                ) {
                    super.onPageStarted(
                        view,
                        url,
                        favicon
                    )

                    Log.d(
                        "EDITOR",
                        "onPageStarted: $url"
                    )

                }

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

                    Log.d(
                        "EDITOR",
                        "onPageFinished: $url"
                    )
                }

                override fun onReceivedError(
                    view: WebView?,
                    request: android.webkit.WebResourceRequest?,
                    error: android.webkit.WebResourceError?
                ) {
                    super.onReceivedError(
                        view,
                        request,
                        error
                    )

                    Log.e(
                        "EDITOR",
                        "onReceivedError: " +
                                "url=${request?.url} " +
                                "code=${error?.errorCode} " +
                                "description=${error?.description}"
                    )

                    AppLogger.log(
                        "EDITOR: onReceivedError: " +
                                "url=${request?.url} " +
                                "code=${error?.errorCode} " +
                                "description=${error?.description}"
                    )
                }

                override fun onReceivedHttpError(
                    view: WebView?,
                    request: android.webkit.WebResourceRequest?,
                    errorResponse: android.webkit.WebResourceResponse?
                ) {
                    super.onReceivedHttpError(
                        view,
                        request,
                        errorResponse
                    )

                    Log.e(
                        "EDITOR",
                        "onReceivedHttpError: " +
                                "url=${request?.url} " +
                                "status=${errorResponse?.statusCode}"
                    )

                    AppLogger.log(
                        "EDITOR: onReceivedHttpError: " +
                                "url=${request?.url} " +
                                "status=${errorResponse?.statusCode}"
                    )
                }
            }

            Log.d("EDITOR", "WebViewClient configured")

            addJavascriptInterface(
                object {

                    @JavascriptInterface
                    fun editorReady() {

                        Log.d(
                            "EDITOR",
                            "JavascriptInterface: editorReady() called"
                        )

                        post {
                            editorReady = true
                        }
                    }

                    @JavascriptInterface
                    fun isDarkMode(): Boolean {

                        return isDark
                    }

                    @JavascriptInterface
                    fun signature(): String? {

                        return selectedAccount?.signature
                    }

                    @JavascriptInterface
                    fun route(): String {

                        Log.d(
                            "EDITOR",
                            "JavascriptInterface: route = $route"
                        )

                        return route
                    }

                    @JavascriptInterface
                    fun setHeight(
                        height: Int,
                        route: String,
                        toolbarHeight: String,
                        editorHeightStr: String,
                        signatureHeight: String
                    ) {

                        Log.d(
                            "EDITOR",
                            "JavascriptInterface: setHeight() called"
                        )

                        post {

                            val density =
                                resources.displayMetrics.density

                            val newHeight =
                                (height * density).toInt()

                            Log.d(
                                "HEIGHT - $route",
                                "Toolbar Height - $toolbarHeight " +
                                        "Editor Height - $editorHeightStr " +
                                        "Signature Height - $signatureHeight " +
                                        "newHeight - $newHeight"
                            )

                            if (height > 0 && editorHeight != height) {

                                Log.d(
                                    "EDITOR",
                                    "Updating Compose WebView height: " +
                                            "$editorHeight -> $height"
                                )

                                editorHeight = height
                            }

                        }
                    }

                },
                "appInterface"
            )

            isVerticalScrollBarEnabled = false
            isHorizontalScrollBarEnabled = false
            overScrollMode = View.OVER_SCROLL_NEVER

            loadUrl(
                "file:///android_asset/editHTML/editor.html"
            )
        }
    },

    update = { view ->

        if (webView !== view) {

            Log.d(
                "EDITOR",
                "AndroidView update(): WebView reference changed"
            )

            webView = view

        } else {

            Log.d(
                "EDITOR",
                "AndroidView update(): same WebView"
            )
        }
    },

    modifier =
        Modifier
            .fillMaxWidth()
            .height(
                editorHeight.coerceAtLeast(300).dp
            )
            .graphicsLayer { }
)
-2
Oct 6 at 5:51 PM
User AvatarGuesser
#android#kotlin

No answer found for this question yet.