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