본문 바로가기

안드로이드

안드로이드 webview bridge 실습

webview bridge 실습

 

구현 내용

웹페이지에서 자바스크립트 코드가 안드로이드 함수를 호출하여 데이터를 전송하고,

안드로이드에서 웹페이지로 데이터를 전송할수 있는 WebView_Bridge 생성

 

구현 순서

1. 실습을 진행할 웹페이지를 assets 폴더를 생성후에 폴더안에 html 파일을 작성합니다. 

2. html 문서에 안드로이드 함수를 호출하는 함수와 안드로이드로부터 데이터를 받을 수 있는 함수를 만듭니다.

3. 안드로이드 레이아웃 화면을 만듭니다.

4. MainActivity와 레이아웃을 연결하고 웹뷰 설정을 합니다.(ex. settings.javaScriptEnabled = true)

5. Bridge 클래스를 생성하고 @JavascriptInterface 어노테이션을 이용하여 자바스크립트에서 호출할 수 있는 함수를 생성한다.

 

생성된 파일

1. MainActivity.kt

2. AndoridBridge.kt

3. webViewTest.html

4. webivew.xml

 

<MainActivity>

package com.example.myapplication

import android.os.Build
import android.os.Bundle
import android.view.View
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import java.time.LocalDateTime


class MainActivity : AppCompatActivity(), AndroidBridge.BridgeListener {

    private val bridge = AndroidBridge()
    var mTextView:TextView?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.webview)
        WebView.setWebContentsDebuggingEnabled(true)
        val myWebView: WebView = findViewById(R.id.webview)

        myWebView.loadUrl("file:///android_asset/webViewTest.html")
        myWebView.apply {
            webViewClient = WebViewClient()
            settings.javaScriptEnabled = true
        }
        myWebView.addJavascriptInterface(bridge, "AndroidBridge")
        bridge.setListener(this)

        val button =findViewById<Button>(R.id.transfer);
        mTextView=findViewById<TextView>(R.id.textView)

        button.setOnClickListener(object: View.OnClickListener{
            @RequiresApi(Build.VERSION_CODES.O)
            override fun onClick(v: View?) {
                val time: LocalDateTime = LocalDateTime.now()
                myWebView.loadUrl("javascript:androidToWeb('Android > Web 전송<br>"+time+"<br>Hello JavaScript')");
            }
        })
    }

    override fun showToast(msg: String) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
        mTextView?.text=msg
    }
}

 addJavascriptInterface()를 사용하면 자바스크립트가 Android 앱을 제어할 수 있게 됩니다. 이는 유용한 기능일 수 있지만 동시에 위험한 보안 문제가 될 수 있습니다.

 

<AndroidBridge>

package com.example.myapplication

import android.webkit.JavascriptInterface
import androidx.appcompat.app.AppCompatActivity


class AndroidBridge  : AppCompatActivity() {

    private var callback: BridgeListener? = null

    fun setListener(listener: BridgeListener) {
        callback = listener
    }

    @JavascriptInterface
    fun makeToast(msg: String) {
        callback?.showToast(msg)
    }

    interface BridgeListener {
        fun showToast(msg: String)
    }
}

 

<webivew.xml>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
           
    <Button
        android:id="@+id/transfer"
        android:layout_width="192dp"
        android:layout_height="49dp"
        android:layout_marginStart="36dp"
        android:text="Android->Web"
        app:layout_constraintBottom_toTopOf="@+id/webview"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.158" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="331dp"
        android:layout_height="112dp"
        android:layout_marginStart="36dp"
        android:layout_marginBottom="20dp"
        android:text="Web에서 받은 메시지"
        app:layout_constraintBottom_toTopOf="@+id/webview"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.681" />

    <WebView
        android:id="@+id/webview"
        android:layout_width="297dp"
        android:layout_height="401dp"
        android:layout_marginStart="36dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.74"
        tools:ignore="WebViewLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

<webViewTest.html>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function webToAndroid(){
            AndroidBridge.makeToast("web에서 안드로이드로 전송, Hello android!!");
        }

        function androidToWeb(arg){
			document.getElementById('textFromApp').innerHTML = arg;
        }
    </script>
</head>
<body>
<button type="button" onclick="webToAndroid()">web->Android</button>
<p id="textFromApp">Android에서 받은 메세지 : </p>
</body>
</html>

 

<실행결과>

 

Screen_.avi
1.40MB

 

 

GitLab 전체 코드: https://gitlab.com/kingdom3/webview_bridge

 

참조

[1] WebView에서 웹 앱 빌드 - 안드로이드 공식문서

https://developer.android.com/guide/webapps/webview?hl=ko

 

[2] 브릿지 통신 - 블로그

https://kotlinworld.com/364

 

[3] 안드로이드 웹뷰와 웹간 스크립트 호출(Bridge) - 블로그

https://jupiter0410.tistory.com/9