Открытие WebView с использованием сопрограмм в Kotlin - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь открыть WebView из моего BottomNavBar, используя Coroutines, но получаю эту ошибку:

java .lang.RuntimeException: java .lang.Throwable: A Метод WebView был вызван в потоке DefaultDispatcher-worker-1. Все методы WebView должны вызываться в одном потоке.

Мой код выглядит следующим образом:

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()
        }
    }
}

Существует ли лучший подход для достижения этой цели? И можно ли загрузить WebViews в другой поток, а не в поток пользовательского интерфейса?

Спасибо:

1 Ответ

1 голос
/ 09 января 2020

Dispatchers.Default использует пул потоков под капотом, и, как исключение говорит вам, WebView ожидает, что его методы будут вызываться из того же Thread, в этом случае UI Thread.

Кроме того, согласно документам runBlocking должны использоваться только основные функции и тесты, так как он блокирует вызывающего Thread до завершения сопрограммы.

И может Веб-представления загружаются в другом потоке, а не в потоке пользовательского интерфейса?

Нет, методы WebView должны вызываться из пользовательского интерфейса Thread

...