일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 소프시스 밤부 좌식 엑슬 테이블
- T자형인재
- 목적중심리더십
- 어떻게 나답게 살 것인가
- 슬기로운 온라인 게임
- 좌식테이블
- 한달어스
- 북한살둘레길
- 프래그먼트
- 아비투스
- 소프시스
- 리얼하다
- 베드테이블
- 지지않는다는말
- 1일1커밋
- 테트리스
- 한달독서
- 면접
- 한단어의힘
- 캐치마인드
- 목적 중심 리더십
- 베드트레이
- 함수형 프로그래밍
- 자취필수템
- 재택근무
- 안드로이드
- 끝말잇기
- 한달브런치북만들기
- 브런치작가되기
- 커스텀린트
- Today
- Total
정상에서 IT를 외치다
[Android, JavascriptInterface] 웹뷰와 앱간의 통신 예제 본문
안녕하세요. 블랙진입니다.
웹뷰를 사용하는 앱을 개발하다 보면 웹뷰와 앱간의 통신이 필요한 경우가 있습니다. 더 자세히 말하자면 웹뷰의 자바스크립트와 안드로이드의 클라이언트 코드의 통신이 필요합니다. 이를 위한 방법으로 javasriptInterface를 사용할 수 있는데요. 그럼 이와 관련된 구글 가이드에 있는 예제를 확인해 보겠습니다.
구글 예제
1. javaScriptEnabled를 활성화 시켜준다.
val myWebView: WebView = findViewById(R.id.webview)
myWebView.settings.javaScriptEnabled = true
2. @JavascriptInterface 함수를 생성해준다.
/** 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()
}
}
3. 위에서 생성한 클래스를 웹뷰에 추가해준다.
val webView: WebView = findViewById(R.id.webview)
webView.addJavascriptInterface(WebAppInterface(this), "Android")
4. 자바스크립트에서 안드로이드에 선언한 함수를 호출할 수 있다.
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
위 예제 그대로 실재 프로젝트에서 어떻게 테스트 할 수 있는지 직접 코드로 확인해 보겠습니다.
프로젝트 코드
1. MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//웹뷰의 자바스크립트 기능을 활성화 시킵니다.
webview.settings.javaScriptEnabled = true
//BlackJin 명의 JavascriptInterface 를 추가해 줍니다.
webview.addJavascriptInterface(WebAppInterface(this), "BlackJin")
//assets에 있는 sample.html을 로딩합니다.
webview.loadUrl("file:///android_asset/sample.html")
}
/** 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()
}
}
}
구글 예제에서는 인터페이스 명을 Android 라고 했지만 저는 BlackJin 으로 변경했습니다.
webview.addJavascriptInterface(WebAppInterface(this), "BlackJin")
2. activity_main
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
3. sample.html 을 생성 후 assets 폴더에 추가해줍니다.
위와 같은 방법으로 클라이언트 코드에서 sample.html을 불러와 테스트 할 수 있습니다. 또한 필요한 경우 얼마든지 html와 script 코드를 수정할 수 있습니다.
sample.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
</head>
<body>
<p>
로딩이 완료된 웹뷰 입니다.
</p>
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Black Jin World!')"/>
<script type="text/javascript">
function showAndroidToast(toast) {
BlackJin.showToast(toast);
}
</script>
</body>
</html>
우리는 1번에서 인터페이스 명을 BlackJin으로 명명했습니다. 그러므로 아래와 같이 {인터페이스명}.{함수} 형식으로 호출해 주면 웹뷰에서 클라이언트에 선언된 코드를 호출할 수 있게 됩니다.
<script type="text/javascript">
function showAndroidToast(toast) {
BlackJin.showToast(toast);
}
</script>
동작
웹뷰의 say hello 버튼을 누르면 toast가 나오는 것을 확인할 수 있습니다. 지금까지 구글의 간단한 예제를 살펴보았는데요.
이는 웹뷰에서 클라이언트 코드만을 호출하는 단순한 예제였습니다.
이번에는 클라이언트의 값을 전달받아 이를 웹뷰에서 가공 후 출력하는 예제를 만들어 보겠습니다. 동작은 아래와 같습니다.
동작
edittext에서 숫자를 받아 button을 클릭하면 입력된 값의 2를 곱한 값을 textview에 출력해 줍니다.
구현
1. activity_main
화면은 위와 같이 웹뷰 영역과 클라이언트 영역으로 나뉩니다. 코드는 아래와 같습니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="100dp" />
<EditText
android:layout_marginTop="20dp"
android:id="@+id/edittext"
android:gravity="center"
android:inputType="number"
android:layout_width="200dp"
android:layout_height="wrap_content"/>
<Button
android:layout_marginTop="20dp"
android:id="@+id/button"
android:text="button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_marginTop="20dp"
android:id="@+id/textview"
android:text="result"
android:textSize="20dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
2. 웹뷰 관련 코드는 아래와 같이 2개의 파일를 준비합니다.
이번에는 html 코드와 js 코드를 분리했습니다.
exam.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
</head>
<body>
화면에 입력한 숫자의 곱하기 2의 값이 화면에 출력됩니다.
<script type="text/javascript" src="exam_script.js"></script>
</body>
</html>
exam_script.js
var exam_script = {
plus_num: function(num){
try{
var result = num * 2
BlackJin.getDoubleNum(result)
}catch(err){
console.log(">> [exam_script.plus_num()] " + err)
}
}
}
자바 스크립트 코드를 보면 num이라는 파라미터를 받아 BlackJin 이름의 인터페이스가 있으면 getDoubleNum 함수를 실행함을 알 수 있습니다.
3. MainAcitivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//웹뷰의 자바스크립트 기능을 활성화 시킵니다.
webview.settings.javaScriptEnabled = true
//BlackJin 명의 JavascriptInterface 를 추가해 줍니다.
webview.addJavascriptInterface(WebViewJavascriptBridge(), "BlackJin")
//assets에 있는 exam.html을 로딩합니다.
webview.loadUrl("file:///android_asset/exam.html")
button.setOnClickListener {
webview.loadUrl("javascript:exam_script.plus_num(" + edittext.text + ")")
}
}
inner class WebViewJavascriptBridge {
@JavascriptInterface
fun getDoubleNum(num: Int) {
textview.text = num.toString()
}
}
}
여기서 중요하게 볼점은 클라이언트 코드에서 웹뷰의 자바스크립트를 호출할 때는 아래와 같은 방식으로 하면 됩니다.
button.setOnClickListener {
webview.loadUrl("javascript:exam_script.plus_num(" + edittext.text + ")")
}
버튼을 클릭하면 자바스크립트의 plus_num을 호출하고 인자로 exittext에 입력된 숫자를 받고 있습니다.
정리
웹뷰와 앱간의 통신하는 방법에 대해서 확인해 보았는데요. 이를 다시 정리하면 아래와 같습니다.
웹뷰 -> 클라이언트 코드 호출
@JavascriptInterface 를 이용한다.
/** 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()
}
}
클라이언트 코드 -> 웹뷰의 자바스크립트 호출
javascript 함수를 loadUrl에서 호출해준다.
webview.loadUrl("javascript:exam_script.plus_num(" + edittext.text + ")")
<참고예제>
'안드로이드' 카테고리의 다른 글
[드로이드 나이츠] 2020 드로이드 나이츠 온라인 내용 정리 (0) | 2020.09.27 |
---|---|
[Android, Room] Room One to Many 관계 살펴보기 (3) | 2020.09.19 |
[Android, MVVM] MVVM 따라하기 - 4 (MVVM 구현) (6) | 2020.06.16 |
[Android, MVVM] MVVM 따라하기 - 3 (RxJava 구현) (2) | 2020.06.09 |
[Android, MVVM] MVVM 따라하기 - 2 (Model 구현) (2) | 2020.06.09 |