Android와 JavaScript 간 상호 작동 구현 방법

WebView를 활용한 안드로이드와 자바스크립트 통신

안드로이드 애플리케이션에서 동적인 UI를 구현하거나 서버에서 관리하는 콘텐츠를 실시간으로 반영해야 할 경우, HTML과 JavaScript 기반의 웹뷰를 사용하는 것이 효과적인 접근 방식이 될 수 있다. 이를 통해 네이티브 코드 재배포 없이도 인터페이스 변경이나 콘텐츠 업데이트가 가능하다. 아래는 안드로이드와 JavaScript가 서로 메서드를 호출하는 방법을 설명한다.

기본 설정: WebView에 JavaScript 활성화

웹뷰에서 JavaScript를 실행하려면 먼저 설정에서 해당 기능을 허용해야 한다. 다음 코드를 통해 JavaScript 실행을 활성화할 수 있다.

WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);

HTML 콘텐츠 로드

로컬 assets 폴더에 저장된 HTML 파일을 로드하려면 다음과 같은 URL 형식을 사용한다.

webView.loadUrl("file:///android_asset/page.html");

또는 원격 서버의 웹 페이지를 로드할 수도 있다.

자바스크립트에서 안드로이드 메서드 호출하기

자바스크립트가 네이티브 안드로이드 코드를 호출하려면 addJavascriptInterface 메서드를 사용해 특정 Java 객체를 JavaScript에 노출시켜야 한다.

webView.addJavascriptInterface(new BridgeObject(), "nativeBridge");

상호 호출 예제

다음은 전화번호 목록을 JSON 형식으로 전달하고, 사용자가 링크를 클릭하면 전화 앱을 실행하는 예제이다.

Java 코드 (MainActivity.java)

public class MainActivity extends AppCompatActivity {
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        webView.loadUrl("file:///android_asset/contacts.html");
        webView.addJavascriptInterface(new NativeController(), "nativeBridge");
    }

    public class NativeController {
        // JavaScript에서 전화 걸기 요청 시 호출
        @JavascriptInterface
        public void initiateCall(String number) {
            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:" + number));
            if (callIntent.resolveActivity(getPackageManager()) != null) {
                startActivity(callIntent);
            }
        }

        // HTML 페이지 로드 후 JS로 데이터 전달
        @JavascriptInterface
        public void fetchContactList() {
            String data = "[{\"name\": \"김민수\", \"balance\": \"5000000\", \"phone\": \"01012345678\"}]";
            webView.post(() -> webView.loadUrl("javascript:renderContacts('" + data + "')"));
        }
    }
}

HTML 및 JavaScript 코드 (assets/contacts.html)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>연락처 목록</title>
  <script type="text/javascript">
    function renderContacts(jsonInput) {
      let contacts = JSON.parse(jsonInput);
      let table = document.getElementById("contactTable");

      contacts.forEach(function(person) {
        let row = table.insertRow();
        let cellName = row.insertCell(0);
        let cellBalance = row.insertCell(1);
        let cellPhone = row.insertCell(2);

        cellName.textContent = person.name;
        cellBalance.textContent = person.balance;
        cellPhone.innerHTML = '<a href="#" onclick="nativeBridge.initiateCall(\'' + person.phone + '\')">' + person.phone + '</a>';
      });
    }
  </script>
</head>
<body onload="nativeBridge.fetchContactList()">
  <table width="100%" id="contactTable" border="1">
    <tr>
      <th>이름</th>
      <th>잔액</th>
      <th>전화번호</th>
    </tr>
  </table>
</body>
</html>

권한 추가

전화 기능을 사용하려면 매니페스트에 권한을 선언해야 한다.

<uses-permission android:name="android.permission.CALL_PHONE" />

안드로이드 6.0(API 레벨 23) 이상에서는 런타임 권한 요청도 필요할 수 있다.

태그: Android WebView JavaScript addJavascriptInterface WebSettings

5월 30일 05:31에 게시됨