개발새발 - IT 기술블로그
article thumbnail

안녕하세요. 이전 포스팅에 이어 웹뷰에 대해 계속 알아보겠습니다. 이전엔 웹뷰를 생성하여 페이지를 로드하는 것 까지 해봤다면, 이번 글에서는 앱에서 웹뷰에 접근하고 제어하는 기능에 대해 알아보겠습니다. 

 

  • 응용프로그램 제어(WebViewClient)
  • 페이지의 방문 기록 탐색
  • 구성 변경 처리
  • 기타 제어

 

웹뷰를 생성하는 부분은 (1)번 포스팅을 참고하시기 바랍니다.

2022.12.26 - [안드로이드 Android] - [Android] 안드로이드 웹뷰(WebView)(1) - 앱 브라우저에서 호출

 

 

 


 

응용프로그램 제어

 

웹뷰에서 웹페이지를 호출할 때 웹 페이지에 의존하여 모든 동작과 제어를 맡길 수도 있지만, 앱에서 웹페이지에 접근하고 페이지의 생성소멸 상태를 인지하기 위해서는 WebViewClient의 메서드를 재정의 해야합니다.

 

 

 

shouldOverrideUrlLoading

val webViewClient: WebViewClient = object : WebViewClient() {

            override fun shouldOverrideUrlLoading(
                view: WebView?,
                request: WebResourceRequest?
            ): Boolean {
                Log.d("TAG_WebView", "shouldOverrideUrlLoading")
                return super.shouldOverrideUrlLoading(view, request)
            }
            
            …
            
        }

 

먼저 웹뷰의 페이지가 바뀌었을 때 호출되는 함수입니다. 

만약 버전별 대응을 위해 함수를 여러번 호출하게 된다면 return 값을 super 키워드가 아닌 true를 반환하여 중복호출을 막아주시면 됩니다.

 

 

onReceiveError

override fun onReceivedError(
    view: WebView?,
    request: WebResourceRequest?,
    error: WebResourceError?
) {
    super.onReceivedError(view, request, error)
    // 페이지를 불러오는 도중 에러가 발생하면 기록삭제 후 빈 화면 로드
    Log.d("TAG_WebView","onReceivedError")
    view?.loadUrl("about:blank")
    view?.clearHistory()
}

페이지를 로드하는 도중 에러가 발생하면 호출되는 함수입니다. 스택된 히스토리를 초기화하고 빈 페이지를 호출하게 하였습니다.

 

 

onPageStarted

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
    super.onPageStarted(view, url, favicon)
    urlTitle.text = url
    Log.d("TAG_WebView","onPageStarted")
}

페이지 로드가 시작될 때 호출되는 함수입니다. 

비즈니스 로직에 대한 처리 혹은 캐시나 쿠키 데이터에 대한 처리에 자주 사용됩니다.

 

 

onPageFinished

override fun onPageFinished(view: WebView?, url: String?) {
    super.onPageFinished(view, url)
    Log.d("TAG_WebView","onPageFinished")
}

페이지 로드가 끝나면 호출되는 함수입니다.

 

 

 

doUpdateVisitedHistory

override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
    super.doUpdateVisitedHistory(view, url, isReload)
    Log.d("TAG_WebView","doUpdateVisitedHistory")
}

위의 함수들을 불러왔음에도 불구하고 호출되지 않는 경우가 있을 수 있습니다.

 

이는 웹페이지가 SPA(Single Page Application)로 구성되어 있냐, MPA(Multiple Page Application)로 구성되어 있냐에 따라 달라집니다.

 

만약 SPA로 구성되어 있다면 페이지의 이동이 아닌 랜더링의 변화로 구성이 변경되기 때문에 shouldOverrideUrlLoading이 호출되지 않을 수 있습니다. 이 땐 doUpdateVisitedHistory를 overriding하여 페이지의 랜더링이 리로드 되었는지 (히스토리가 갱신 되었는지) 를 확인할 수 있습니다.

 

 

 

페이지 방문기록 탐색

웹뷰는 자동으로 웹페이지에 접근한 기록이 저장됩니다. 

goBack() 메서드로 이전 페이지로 이동 할 수 있으며, goForward() 메서드로 다음 페이지로 이동 할 수 있습니다.

또한, canGoBack()canGoForward() 메서드로 저장된 이전 혹은 다음 페이지가 존재하는지 여부를 알 수 있습니다.

val back: ImageView = findViewById(R.id.webViewBackIv)
back.setOnClickListener() {
    if (webView.canGoBack())	// 저장 된 이전 페이지가 있는지 확인
        webView.goBack()    	// 이전 페이지 로딩
    else
        finish()
}

val forward: ImageView = findViewById(R.id.webViewForwardIv)
forward.setOnClickListener() {
    if (webView.canGoForward()) 	// 저장 된 다음 페이지가 있는지 확인
       webView.goForward()		// 다음 페이지 로딩
    
}

 

구성 변경 처리

안드로이드는 멀티 윈도우 모드를 사용하거나 윈도우를 회전하는 경우 onDestroy()가 호출된 후 onCreate()가 다시 호출됩니다. 그럼 웹뷰가 페이지를 다시 로딩하게 되는데 이 현상을 방지하기 위해 configChanges 속성을 사용하여 구성 변경 도중 객체를 보존 할 수 있습니다. 

 

AndroidManifest.xml

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
          android:label="@string/app_name">

이 속성은 화면의 방향성 혹은 크기, 트리거, 키보드 가용성의 변화 등을 감지하여 페이지의 재시작을 막아줍니다.

 

 

기타 제어

 

화면 새로고침 - reload()

val refresh: ImageView = findViewById(R.id.webViewRefreshIv)
refresh.setOnClickListener() {
    webView.reload()
}

 

 

스크롤 맨 위로 올리기 - scrollTo(int, int)

val upScroll: ImageView = findViewById(R.id.webViewUpIv)
upScroll.setOnClickListener() {
    webView.scrollTo(0, 0)		// (x , y)
}

 

+ 2023-09-18 추가 :

페이지의 맨 위 혹은 아래로 이동하는 메서드는 위와같이 구현할 수 있지만, pageUp()과 pageDown()을 사용할 수도 있습니다.

webView.pageUp(true)	// 페이지 상단으로 이동
webView.pageDown(true)	// 페이지 하단으로 이동

 

 

이렇게 웹뷰를 사용하는 기본적인 방법에 대해 알아보았습니다. 이 밖에도 매우 여러가지의 기능들과 처리들이 존재하기 때문에, 웹의 구성방식과 앱과의 통신방식에 따라 사용되는 기능들을 찾아서 사용하시면 되겠습니다. 

감사합니다.

 

 

2023-09-04 추가 : 웹페이지에서 캐시를 사용하는 방법에 대한 포스트가 업로드되었습니다.

2023.09.04 - [Android] - [안드로이드] 웹뷰(WebView)(3) - 브라우저 캐시 사용하기

 

 

참고

https://developer.android.com/develop/ui/views/layout/webapps/webview?hl=ko 

 

Build web apps in WebView  |  Android Developers

If you want to deliver a web application (or just a web page) as a part of a client application, you can do it using WebView. The WebView class is an extension of Android's View class that allows you to display web pages as a part of your activity layout.

developer.android.com

 

https://developer.android.com/guide/topics/resources/runtime-changes?hl=ko 

 

구성 변경 처리  |  Android 개발자  |  Android Developers

구성 변경 처리 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 일부 기기 설정은 런타임에 변경될 수 있습니다(예: 화면 방향, 키보드 가용성 그리고 사용자

developer.android.com

 

 

 

코드

https://github.com/tekken5953/WebViewExam

 

GitHub - tekken5953/WebViewExam

Contribute to tekken5953/WebViewExam development by creating an account on GitHub.

github.com