dev/aos

[AOS] 웹뷰 WebView Guide

캄춰 2023. 10. 23. 15:15
728x90
반응형

하이브리드의 꽃, 

안드로이드와 웹뷰를 매우 잘 알고 사용하기 위해 정리

 

가이드 링크 : https://developer.android.com/guide/webapps/webview?hl=ko

 

WebView에서 웹 앱 빌드  |  Android 개발자  |  Android Developers

WebView에서 웹 앱 빌드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 웹 애플리케이션 또는 웹페이지만 클라이언트 애플리케이션의 일부로 제공하려는 경

developer.android.com

 

 

WebView는 View의 확장 개념이며, 안드로이드에서 웹 페이지를 보기 위함

 

 

1. 로컬 페이지를 띄우는 것이 아니면 인터넷 권한 획득

    <manifest ... >
        <uses-permission android:name="android.permission.INTERNET" />
        ...
    </manifest>

 

내부 이미지 로드

android:usesCleartextTraffic="true">

 

 

2. WebView에 웹 페이지 띄우기

: 현재 blog를 띄울 예정

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val blogUrl = "https://cavedwellers.co.kr"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)

        binding = ActivityMainBinding.inflate(layoutInflater)
        binding.webView.loadUrl(blogUrl)
    }
}

 

위의 방법은 웹 페이지가 앱 내에서 띄어지는 것이 아닌 앱 밖에서 띄어지게 된다.

앱 안에서 띄우고 싶고, 또 동작을 주고 받고 싶으면 설정이 필요하다.

 

 

 

3. 설정

  • WebChromeClient : 전체 화면 지원, WebView가 창을 만들거나 닫을 때 사용자에게 전달 됨(로딩중 이런 것)
	생성자 - WebChromeClient
	
	공개 메소드
	getDefaultVideoPoster() 
	: 재생되지 않을 때 비디오 요소는 '포스터'이미지로 표시된다.
	return Bitmap
	
	getVideoLoadingProgress()
	: 전체 화면 비디오 버퍼링이 진행되는 동안 표시할 뷰를 얻음
	return View
	
	onConsoleMessage(ConsoleMessage consoleMessage) 
	: Javascript콘솔 메시지를 호스트 애플리케이션에 보고
	return boolean
	
	onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) 
	: 새 창을 생성하도록 호스트 응용 프로그램에 요청
	return boolean 
	
	onJsAlert(Web view, String url, String message, JsResult result) 
	: 웹 페이지가 JavaScript alert()대화 상자를 표시하려고 함을 호스트 애플리케이션에게 알림
	return boolean
	
	onJsBeforeUnload(WebView view, String url, String message, JsResult result) 
	: 웹 페이지가 JavaSciprt에서 탐색을 확인하려고 함을 호스트 애플리케이션에 알림
	return boolean
	
	onJsConfirm(WebView view, String url, String message, String defaultValue, JsPromptResult result)
	: 웹 페이지가 JavaScipt prompt대화 상자를 표시하려고 함을 호스트 애플리케이션에 알림
	return boolean
	
	onPermissionRequest(PermissionRequest request)
	: 웹 콘텐츠가 지정된 리소스에 액세스하기 위한 권한을 요청하고 있으며 현재 권한이 부여되거나 거부되지 않았음을 호스트 애플리케이션에 알림
	return void
	
	onPermissionRequestCanceled(PermissionRequest request)
	: 해당 권한 요청이 취소되었음을 호스트 애플리케이션에 알림
	return void
	
**	onProgressChanged(WebView view, int newProgress)
	: 호스트 애플리케이션에 페이지 로드의 현재 진행 상황을 알려줌
	return void
	
	onRequestFocus(Webview view)
	: webview에 대한 표시 및 포커스를 요청
	return void
	
	onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
	: 현재 페이지가 전체 화면 모드로 전환되었음을 호스트 애플리케이션에 알림
	return void
	
	onShowFileChooser(Webview webview, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParam)
	: 클라이언트에게 파일 선택기를 표시하라고 지시함
	return boolean

 

  • WebViewClient : 콘텐츠 렌더링에 대한 이벤트 처리, 웹뷰와의 오고 가는 무언가를 처리한다고 보면 됨
    • webViewClient = WebViewClient() : webView내에서 웹 페이지가 호출되도록 할 수 있음
    • shouldOverrideUrlLoading 오버라이드 함수 : 현재 웹 페이지에서 무엇을 클릭 했는지 알 수 있음
  • WebSettings : 자바 스크립트 사용 설정
    • userAgentString : client의 버전, 기종을 알 수 있음 
    • javaScriptEnabled = true : 자바 스크립트 사용
    • setChacheMode : 웹 페이지의 캐싱 동작을 설정하는 것, 계속해서 페이지를 새로고침 할 것인지, 아니면 기존의 캐시데이터가 있는지 확인하여 빠르게 가져올 것인지 설정하는 것(default: WebSettings.LOAD_DEFAULT)
      1. javaScriptEnabled = true:
        • 설명: 이 설정은 WebView에서 JavaScript를 활성화 또는 비활성화 하는 데 사용됩니다. JavaScript가 활성화되면 WebView는 동적이고 상호 작용 가능한 웹 콘텐츠를 렌더링할 수 있습니다.
      2. javaScriptCanOpenWindowsAutomatically = true:
        • 설명: 이 속성은 JavaScript 코드에 의해 새 창(팝업)이 열리는 것을 허용하는지 여부를 결정합니다. true로 설정하면 JavaScript 코드가 새 창을 열 수 있습니다.
      3. allowContentAccess = true:
        • 설명: WebView에서 웹 콘텐츠에 대한 액세스를 허용할지 여부를 결정합니다. true로 설정하면 WebView가 웹 페이지의 콘텐츠에 대한 액세스를 허용합니다.
      4. loadsImagesAutomatically = true:
        • 설명: 이미지 자동로딩을 활성화 또는 비활성화하는 데 사용됩니다. true로 설정하면 WebView가 웹 페이지에서 자동으로 이미지를 로드합니다.
      5. useWideViewPort = true:
        • 설명: 이 설정은 WebView가 더 넓은 화면 뷰포트를 사용하여 웹 페이지를 렌더링하는 데 도움을 줍니다. true로 설정하면 웹 페이지가 화면의 크기에 맞게 더 잘 맞게 됩니다. 특히, 초기 뷰포트의 크기를 장치의 물리적 크기에 맞게 확대합니다.
      6. loadWithOverviewMode = true:
        • 설명: 이 설정은 WebView가 초기에 페이지를 로드할 때, 웹 페이지의 전체 내용을 화면에 맞추어 줌 아웃하여 보여주도록 합니다. 일반적으로 이것은 페이지의 초기 뷰포트 크기를 더 확대시키는 효과가 있습니다.
        • 용도: 특히, 이 설정은 모바일 환경에서 웹 페이지가 더 작은 화면 크기에 대응하도록 하거나, 초기 로딩 시 사용자에게 전체 콘텐츠를 보여주는 데 유용합니다.
      7. setDomStorageEnabled = true;
        1. DOM 스토리지는 웹 페이지에서 클라이언트 측 데이터를 저장하는 데 사용되는 웹 스토리지 기술 중 하나입니다. 이는 세션과 관계없이 데이터를 로컬에 저장하고 검색할 수 있는 기능을 제공합니다.
      8. webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setAppCacheEnabled(true);
        webView.getSettings().setLoadsImagesAutomatically(true);
        webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
      1. 캐시 사용 활성화:
        • 웹페이지의 리소스를 로컬에 캐싱하면 페이지 로딩 속도가 향상될 수 있습니다. webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);와 같은 방법으로 캐시 사용을 활성화할 수 있습니다.
      2. 쿠키 허용:
        • 쿠키를 허용하면 로그인 정보 등이 유지되어 사용자 경험이 향상됩니다. webView.getSettings().setAcceptCookie(true);로 쿠키 허용을 설정할 수 있습니다.
      3. 하드웨어 가속 활성화:
        • 하드웨어 가속을 사용하면 그래픽 처리가 더 빠르게 이루어져 부드러운 스크롤링 및 애니메이션을 제공할 수 있습니다. webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);와 같이 하드웨어 가속을 활성화할 수 있습니다.
      4. 네트워크 관련 설정:
        • 네트워크 관련 설정을 통해 네트워크 연결이 느릴 때의 대처를 조절할 수 있습니다. webView.getSettings().setBlockNetworkImage(false);와 같이 이미지 로딩을 허용하거나 차단하는 등의 설정을 조절할 수 있습니다.
        • webView.getSettings().setBlockNetworkImage(false)에서 setBlockNetworkImage(false)는 이미지 로딩을 허용하는 설정입니다. 즉, false 값을 사용하면 이미지 로딩이 허용되며, true 값을 사용하면 이미지 로딩이 차단됩니다.
      5. 안전한 연결 사용 (HTTPS):
        • 보안을 강화하기 위해 웹뷰에서는 HTTPS를 사용하는 것이 좋습니다. 또한, webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);와 같이 혼합 콘텐츠를 차단하여 보안을 강화할 수 있습니다.
      6. 타임아웃 설정:
        • 웹페이지나 리소스의 로딩이 지연될 경우, 타임아웃 값을 적절히 설정하여 사용자 경험을 향상시킬 수 있습니다. webView.getSettings().setTimeout(10000);와 같이 타임아웃 값을 설정할 수 있습니다.

 

 

4. Javascript Interface, HTML script와 데이터 주고 받기

: script → Android로 데이터를 전달하는 방법

 

먼저, 주고 받을 클래스를 만든다

: 함수에 다음과 같은 어노테이션을 추가

: @JavascriptInterface

class WebAppInterface(private val context:Context) {
	@JavascriptInterface
    fun showToast(toast:String) { ... }
    
    @JavascriptInterface
    fun calculate(a: Int, b: Int) { ... }
}

 

 

 

Android와 Web연결

: 연결명은 "AndroidCode"로 설정

	webView.addJavaScriptInterface(WebAppInterface(this.baseContext), "AndroidCode")

 

 

 

그럼, HTML단의 script에서 "AndroidCode"이름으로 위의 @JavascriptInterface로 연결된 함수 호출

	<input type="button" value="Practice Send Data" onClick="showAndroidTest('Hello World')" />
    
    <script type="text/javascript">
    	function showAndroidTest(toast) {
        	AndroidCode.showToast(toast)
        }
    </script>

 

 

 

+ 2023-12-01 추가

5. Asset폴더의 html을 load하기

2023.12.01 - [dev/aos] - [AOS] asset폴더 만들기/생성

: asset폴더를 만들고 그대로 경로를 사용하면 안된다.

: file:///assets/something.html 이 아니라 

: assets부분을 android_asset 이라고 명시해주어야 한다.

: file:///android_asset/something.html

    <input type="button" value="Neander Button" onClick="shareLinkToApp('intent:something', 'https://www.naver.com')" />

<script type="text/javascript">
    function shareLinkToApp(intent, url) {
        neander.shareLinkToApp(intent, url);
    }
</script>

 

잘 전달 된다.

    inner class JsBridge() {
        @JavascriptInterface
        fun shareLinkToApp(intent: String, url: String) {
            NLog.d("shareLinkToApp..")
            NLog.i("intent:$intent")
            NLog.i("url:$url")

            // binding.webView.loadUrl(url)     // 그냥 선언하면 looper에 닿질 않는다
            CoroutineScope(Dispatchers.Main).launch {
                binding.webView.loadUrl(url)
            }
        }
    }

 

 


+ 2024-01-08-월 웹뷰 개수확인

: copyBackForwardList()

NLog.d("webViewCount..size:${webView.copyBackForwardList().size}")
NLog.d("webViewCount..currentIndex:${webView.copyBackForwardList().currentIndex}")
webView.goBack()

 

shouldOverrideUrlLoading에서 clearHistory를 해주었는데 동작되지 않는다면,

Boolean타입 프로퍼티를 하나 두고, onPageFinished에서 해당 페이지에서 clearHistory를 진행해주면 된다.

 

728x90
반응형

'dev > aos' 카테고리의 다른 글

[AOS] launchMode정리  (4) 2023.10.30
[AOS] 다른 화면 띄우기 (Activity)  (2) 2023.10.26
[AOS] DataBinding XML이벤트 주고 받기  (0) 2023.10.18
[AOS] 라이브러리(Library) 추가 방법  (0) 2023.10.15
[AOS] ViewModel 생성하기  (0) 2023.10.14