Android에서 JS를 통해 WebView와 통신하기

안녕하세요. 첫 포스팅을 게재하는 명동콜링입니다.

첫 포스팅인 만큼 간단하게 하이브리드 앱 개발 할 때 필수적인 요소인 Javascript를 통해 Web에서 App으로 데이터를 보내는 방법을 알려드리고자 합니다.

하이브리드 앱도 앱이기 때문에 웹 페이지로 구성이 되어있지만 앱의 기능을 어느 정도는 사용하게 됩니다. 그렇기 때문에 앱에서는 웹에서 어떠한 신호를 받기 위한 로직이 필요했으며, 그에 따라 생겨난 것이 Javascript를 통해 데이터를 주고받을 수 있도록 한, Android Bridge Interface 입니다.

과거에 JS를 통해 교류할 수 없었을 때에는 앱 내에서만 사용할 Scheme을 가지고 URL형식으로 호출을 하게 되었다면, 지금은 완벽하게 Javascript문법을 통해 앱의 API를 호출 할 수 있도록 도와주고 있습니다.

그럼 이제 초기 셋팅을 해보도록 할텐데, 전반적인 프로세스는 다음과 같습니다.
  1. Android WebView에서 Javascript Interface를 설정한다.
  2. Web에서는 WebView에서 설정된 Interface를 호출한다.
항목이 두 가지 밖에 없는 만큼 참 구현도 간단한데, 예시로 웹에서 버튼을 누르면 현재의 웹이 아닌 다른 브라우저에서 페이지가 열리도록 하는 것을 구현해 보도록 하겠습니다.

먼저 WebView에서 Javascript Interface를 설정하는 방식에 대해 확인해 봅시다.

1
2
3
4
5
public abstract class JavascriptInterface{
    public static final String JS_INTERFACE = "webInterface";
    public abstract void loadPage(String url);
}
cs

 위의 클래스는 기본 클래스가 아닌 추상 클래스 입니다. 인터페이스 개발방식은 개발자의 입맛에 따라 다르게 개발 할 수 있지만, 간단한 예시를 위해 만들었습니다.

 이렇게 클래스만 작성해야 되는 것이냐... 아직 WebView와 연결이 되지 않았기 때문에 작동은 하지 않습니다. 해당 추상 메소드에는 추후에 웹 브라우저로 팅기는 로직을 작성할 것 입니다.

 그럼 이번에는 연결을 해보도록 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
public void onCreate(/**/){
    setContentView(R.layout.....);
    WebView webView = (WebView)findViewById(R.id.webView);
    webView.addJavascriptInterface(new JavascriptInterface(){
        @JavascriptInterface
        public void loadPage(String url){
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(url));
            startActivity(intent);
        }
    }, JavascriptInterface.JS_INTERFACE);
}
cs

WebView와 JavascriptInterface를 연결 하기 위해서는 WebView의 addJavascriptInterface를 사용합니다.

첫번째 파라미터는 JavascriptInterface에 대한 상세 로직을 구현하며, 두번째 파라미터는 Web에서 앱을 호출할 인터페이스 네이밍을 지정합니다.

또 한가지 주의 할 점이라 하면, loadPage 메소드를 정의할 때 @JavascriptInterface라는 Annotation을 붙여주어야 Web페이지에서 메소드가 정의되었는지 확인할 수 있습니다. 써 있지 않게되면 실행이 되지 않습니다.

여기까지 첫번째 로직 구현이 완료되었고, 다음 두번째 WebView에서 설정된 Interface를 호출하는 방법을 보도록 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
<html>
    <head>
        <script>
            function linkPage(){
                window.webInterface.loadPage("http://www.naver.com");
            }
        </script>
    </head>
    <body>
        <button onclick="linkPage();">Press</button>
    </body>
</html>
cs
다음과 같이 하면 두번째 로직도 구현이 완료됩니다.

여기서 메소드로 구현된 linkPage 안의 로직을 중요하게 보면 되겠습니다. 웹에서 앱에 호출을 하고자 할 때에는 window 객체에 들어가진, 미리 약속해 놓았던 인터페이스 네이밍을 사용하고, 네이밍 내부에 정의해놓았던 메소드에 접근할 수 있습니다. 그래서 앱에서 인터페이스 연결을 할 때 사용했던 webInterface 라는 네이밍을 통하여 loadPage 메소드를 접근할 수 있게 되는 것입니다.

이렇게 간단하게 웹에서 앱으로 간단하게 통신 해보았는데, 이해가 되신다면 더 편하신 방법으로 개발하시면 되겠습니다.

여기서 포스팅을 마치겠습니다. 감사합니다!



댓글

주간 인기글

[정보] 인스타그램은 당신의 소리를 '듣고' 있을 수도 있습니다

카드뉴스 마케팅 팁

[iOS 강좌] 오픈소스로 쉽게 카메라 앱 만들기 - 1부(cocospods)

[정보] Git을 이용한 형상관리 #1 - Git의 세가지 상태, Git 설치

[AWS] Amazon Polly 한국어 서비스 지원