WebView 사용법
1. 권한 요청
- WebView를 사용하기 위해선 인터넷 권한이 필요
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
2. 앱에 WebView 추가
- xml에서 추가
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
- Activity에서 추가
val myWebView: WebView = findViewById(R.id.webview)
myWebView.loadUrl("http://www.example.com")
3. 웹 페이지 로드
loadUrl()
- url로 로드
val myWebView:WebView = findViewById(R.id.webview)
myWebView.loadUrl("http://www.example.com")
- 로컬에서 로드
val myWebView:WebView = findViewById(R.id.webview)
webView.loadUrl("file:///android_asset/gooddoc.html")
assets 디렉토리는 main 밑에 존재
loadData()
- html 문자열로 로드
// Create an unencoded HTML string
// then convert the unencoded HTML string into bytes, encode
// it with Base64, and load the data.
val unencodedHtml =
"<html><body>'%23' is the percent code for ‘#‘ </body></html>"
val encodedHtml = Base64.encodeToString(unencodedHtml.toByteArray(), Base64.NO_PADDING)
myWebView.loadData(encodedHtml, "text/html", "base64")
💡참고 : 이 HTML로 수행할 수 있는 작업에는 제한이 있음
인코딩 옵션에 관한 자세한 내용은 loadData() 및 loadDataWithBaseURL() 을 참조
기타 예시 블로그 [Android] webView 에 html String Data 넣어서 불러오기
WebView에서 자바스크립트 사용 (브릿지, Bridge)
WebView에 로드하려는 웹페이지가 자바스크립트를 사용하는 경우 자바스크립트를 사용하도록 설정해야 함
자바스크립트 사용 설정을 하면 앱 코드와 자바스크립트 코드 간에 인터페이스를 만들 수 있음
1. 자바스크립트 사용 설정
- 기본적으로 자바스크립트는 WebView에서 사용 중지 됨
- WebView에 연결된 WebSettings를 통해 자바스크립트 사용 설정 가능
val myWebview: WebView = findViewById(R.id.webview)
myWebView.settings.javaScriptEnabled = true
- getSettings()로 WebSettings를 가져온 다음 setJavaScriptEnabled()로 사용 설정 가능
2. 자바스크립트와 Android 간의 인터페이스 생성
Android 코드와 자바스크립트 코드 간에 인터페이스를 만들 수 있음. WebView의 이벤트처리를 Android 코드로 할 수 있다고 생각하면 됨
- ex) 자바스크립트에서 alert() 대신 Android의 메소드 호출 가능
ex) 웹 페이지로부터 문자열을 받아서 Toast 메세지를 띄우는 예시
/** Instantiate the interface and set the context */
class WebAppInterface(private val mContext: Context) {
/** Show a toast from the web page */
/** 어노테이션 필수 */
@JavascriptInterface
fun showToast(toast: String) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show()
}
}
위에선 메소드 내에서 바로 동작을 지정하였지만, 인터페이스 클래스에 생성자로 동작을 지정할 콜백(또는 람다)를 전달 받으면 됨
메소드 내에선 invoke를 통해 해당 콜백(또는 람다) 함수를 실행
주의: targetSdkVersion을 17 이상으로 설정한 경우
자바스크립트에 사용 가능하게 할 모든 메서드에 @JavascriptInterface주석을 추가해야 함 (메소드도 public이어야 함)
주석을 작성하지 않으면 Android 4.2 이상에서 실행될 때 웹페이지가 메서드에 액세스할 수 없음
3. 자바스크립트에서 Android 코드 호출
자바스크립트 <-> Android 간의 새 인터페이스를 결합하려면 addJavascriptInterface() 메소드로 호출 될 클래스를 전달하면 됨
val webView: WebView = findViewById(R.id.webview)
webView.addJavascriptInterface(WebAppInterface(this), "Android")
WebView를 생성하는 시점에 addJavascriptInterface() 메소드에게 전달하여 결합 가능
이제 WebView에 띄워진 웹 페이지가 Android 코드에 액세스할 수 있음
아래와 같이 click 이벤트가 발생하면 Android의 코드를 실행
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
html에서 Android의 메소드를 호출하는 형태이므로, 일반적으로 프론트 측에서 scheme를 전달해줌
해당 scheme을 보고 그에 맞춰 인터페이스(+ 메소드)를 작성해주면 됨
💡참고 : 자바스크립트에 결합된 객체는 객체가 생성된 스레드가 아닌 다른 스레드에서 실행 됨
4. Android에서 자바스크립트 호출
자바스크립트에서 Android의 메소드를 호출할 수 있는 것처럼 반대로도 가능
Html에서 호출 될 자바스크립트 메소드를 작성
<script>
function receiveData(str){
document.getElementById('sendTest').innerHTML = str;
}
</script>
버튼 클릭 이벤트 리스너 등록
loadUrl()로 javascript를 호출할 수 있음
private fun initBtn(){
sendBtn.setOnClickListener {
webView.loadUrl("javascript:receiveData('버튼 누른 횟수 = ${cnt++}회')")
}
}
기타 WebSettings 속성
//WebView 화면크기에 맞추도록 설정 - setUseWideViewPort 와 같이 써야함
webView.settings.loadWithOverviewMode = true;
//wide viewport 설정 - setLoadWithOverviewMode 와 같이 써야함
webView.settings.useWideViewPort = true;
//줌 설정 여부
webView.settings.supportZoom = false;
//줌 확대/축소 버튼 여부
webView.settings.builtInZoomControls = true;
//자바스크립트 사용 여부
webView.settings.javaScriptEnabled = true);
//자바스크립트가 window.open()을 사용할 수 있도록 설정
webView.settings.javaScriptCanOpenWindowsAutomatically = true;
//멀티윈도우 사용 여부
webView.settings.supportMultipleWindows = true;
// 캐시 사용 여부
webView.getSettings().setAppCacheEnabled(false);
// 캐시 설정
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// LOAD_CACHE_ELSE_NETWORK : 캐시 기간만료 시 네트워크 접속
// LOAD_CACHE_ONLY : 캐시만 불러옴 (네트워크 사용 X)
// LOAD_DEFAULT : 기본 모드, 캐시 사용, 기간 만료 시 네트워크 사용
// LOAD_NO_CACHE : 캐시모드 사용안함
// LOAD_NORMAL : 기본모드 캐시 사용 @Deprecated
// 로컬 스토리지 (localStorage) 사용여부
webView.getSettings().setDomStorageEnabled(true);
// 폼에 입력된 데이터 저장 여부
webView.getSettings().setSaveFormData(true);
// 파일 액세스 허용 여부
webView.getSettings().setAllowFileAccess(true);
// 디버그 모드 사용 여부
// true 인 경우 크롬에서 "chrome://inspect" 를 통해 웹뷰 확인 가능
webView.setWebContentsDebuggingEnabled(false);
// 사용자 문자열 설정
webView.getSettings().setUserAgentString("app");
// 인코딩 설정
webView.getSettings().setDefaultTextEncodingName("UTF-8");
// 네트워크를 통해 이미지리소스 받을지 여부
webView.getSettings().setBlockNetworkImage(false);
// database storage API 사용 여부
webView.getSettings().setDatabaseEnabled(false);
// 웹뷰를 통해 Content URL 에 접근 사용 여부
webView.getSettings().setAllowContentAccess(true);
'안드로이드 > 이론' 카테고리의 다른 글
[ 안드로이드 ] ViewPager2 안에 WebView 중첩 Swipe 처리 (0) | 2023.07.12 |
---|---|
[ 안드로이드 ] WebView 페이지 탐색 처리 (0) | 2023.07.06 |
[ 안드로이드 ] 클릭 가능한 모든 뷰에 반투명 효과 넣기 (0) | 2023.05.20 |
[ 안드로이드 ] Retrofit2를 이용하여 서버와 통신하기 (2) - 예시 (0) | 2023.05.04 |
[ 안드로이드 ] Retrofit2를 이용하여 서버와 통신하기 (1) - 안전하게 통신하기 (SafeApiCall) (0) | 2023.05.04 |