在 Kotlin 中使用协程打开 WebView

Opening a WebView using Coroutines in Kotlin

我正在尝试使用协程从我的 BottomNavBar 打开 WebView,但出现此错误:

java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'DefaultDispatcher-worker-1'. All WebView methods must be called on the same thread.

我的代码如下所示:

class WebViewFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_web_view, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        openWebView()
    }

    private suspend fun showWebView(){
        if(webView != null){

            webView!!.webViewClient = WebViewClient()
            webView!!.webChromeClient = WebChromeClient()

            val webSettings = webView!!.settings
            webSettings.javaScriptEnabled = true

            webView!!.loadUrl("https://www.google.com")

            webView!!.webViewClient = object: WebViewClient(){
                override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                    progressBar.visibility = View.VISIBLE
                    super.onPageStarted(view, url, favicon)
                }

                override fun onPageFinished(view: WebView?, url: String?) {
                    progressBar.visibility = View.GONE
                    super.onPageFinished(view, url)
                }
            }
        }
    }

    private fun openWebView(){
        runBlocking(Dispatchers.Default) {
            showWebView()
        }
    }
}

是否有实现此目的的最佳方法? WebView 是否可以加载到另一个线程而不是 UI 线程?

谢谢:

Dispatchers.Default 在后台使用了一个线程池,并且异常告诉你 WebView 期望从同一个 Thread 调用它的方法,UI Thread 在这种情况下。

另外,根据 docs runBlocking 应该只被主要函数和测试使用,因为它会阻塞调用者 Thread 直到协程完成。

And can WebViews be loaded on another thread rather the UI thread?

不,应该从 UI Thread

中调用 WebView 方法