$30 off During Our Annual Pro Sale. View Details »

WebViewと向き合う

mkeeda
September 25, 2023

 WebViewと向き合う

DroidKaigi.onCompletion { 2023@Online } の発表資料です
https://yumemi.connpass.com/event/289949/

サンプルコード
https://github.com/mkeeda/webview-sandbox

mkeeda

September 25, 2023
Tweet

More Decks by mkeeda

Other Decks in Programming

Transcript

  1. WebView
    DroidKaigi.onCompletion {
    20
    23
    @Online }


    (@mr_mkeeda)

    View Slide

  2. About me


    Twitter: @mr_mkeeda


    Github: @mkeeda


    Android Engineer at Cybozu, Inc


    kintone


    2

    View Slide

  3. WebView
    WebView
    3

    View Slide

  4. WebView
    URL/HTML





    4

    View Slide

  5. UI
    5
    WebView Fragment
    loadUrl( URL)
    reload()
    WebViewClient
    onPageStarted()
    onPageFinished()
    shouldOverrideUrlLoading()

    View Slide

  6. WebView Fragment
    loadUrl( URL)
    reload()
    WebViewClient
    onPageStarted()
    onPageFinished()
    shouldOverrideUrlLoading()
    6
    Fragment


    500 WebView




    View Slide

  7. 7
    https://developer.android.com/topic/architecture

    View Slide

  8. UI
    8
    UI


    Elements
    UI


    State
    = UI

    View Slide

  9. : Web
    9
    UI


    Elements
    UI


    State
    = UI
    WebView URL Web
    =

    View Slide

  10. = URL
    10
    UI elements


    WebView
    UI state


    URL A =
    UI


    Web


    A
    UI elements


    WebView
    UI state


    URL B =
    UI


    Web


    B


    View Slide

  11. WebView
    11
    UI elements


    WebView
    State holder


    ViewModel
    UI state


    URL
    3. URL
    2
    . URL


    (UI event)
    1. URL


    4. URL

    View Slide

  12. 12
    UI elements


    WebView
    State holder


    ViewModel
    UI state


    URL
    UI state
    UI state


    View Slide

  13. WebView
    android.widget UI state


    Callback


    UI state WebView
    13
    UI state


    URL
    UI elements


    WebView

    View Slide

  14. URL
    14
    WebViewClient
    shouldOverrideUrlLoading()
    UI elements


    WebView
    UI state


    URL A
    State holder


    ViewModel

    return true
    loadUrl()


    UI state


    URL B
    WebViewClient#

    shouldOverrideUrlLoading()


    true URL


    URL
    UI state


    URL B

    View Slide

  15. 15
    class WebViewModel : ViewModel() {
    private val _currentUrl =
    MutableStateFlow(Uri.parse("https://www.google.com"))
    val url: StateFlow = _currentUrl.asStateFlow()
    fun onPageLoad(newUrl: Uri) {
    _currentUrl.update { currentUrl ->
    // ೚ҙͷϩδοΫ


    // …
    newUrl
    }
    }
    }
    // Composeableؔ਺
    val url by viewModel.url.collectAsStateWithLifecycle()
    WebScreen(
    url = url,
    onUrlChanged = { newUrl ->
    viewModel.onPageLoad(newUrl)
    }
    )

    View Slide

  16. 16
    @Composable
    fun WebScreen(
    url: Uri,
    onUrlChanged: (Uri) -> Unit
    ) {
    AndroidView(
    factory = { context ->
    WebView(context).apply {
    webViewClient =
    MyWebViewClient(onUrlChanged)
    }
    },
    update = { webView ->
    webView.loadUrl(url.toString())
    }
    )
    }
    class MyWebViewClient(
    private val onUrlChanged: (Uri) -> Unit
    ) : WebViewClientCompat() {
    override fun shouldOverrideUrlLoading(
    view: WebView,
    request: WebResourceRequest
    ): Boolean {
    onUrlChanged(request.url)
    return true
    }
    }

    View Slide

  17. WebView UI state



    https://github.com/mkeeda/webview-sandbox



    WebView
    17
    Do not call WebView#loadUrl(String) with the request's URL and then return true.


    This unnecessarily cancels the current load and starts a new load with the same URL.


    https://developer.android.com/reference/android/webkit/WebViewClient

    View Slide