안드로이드 웹뷰와 브라우저의 차이점(feat. 하이브리드앱의 어려움)

웹뷰를 사용하여 앱을 개발할 때, 많은 개발자들은 웹뷰가 브라우저와 동일하게 작동할 것이라고 기대합니다.

그러나 실제로는 많은 차이점이 있으며, 이로 인해 다양한 어려움에 직면하게 됩니다.

이러한 차이점과 문제점, 그리고 이를 극복하는 방법에 대해 알아보겠습니다.


1.안드로이드 웹뷰로 앱을 개발하면 브라우저와 어떤 문제가 발생할까?

1)소셜 로그인 문제 발생

웹뷰에서 소셜 로그인을 구현하는 것은 브라우저에서와 달리 많은 문제가 발생할 수 있습니다.

이전 포스팅에서 설명한 것처럼 구글과 페이스북 로그인 시 “user agent disallowed” 에러가 발생하는데, 이는 웹뷰의 보안 문제와 사용자 경험 보호를 위해 구글과 페이스북이 웹뷰에서의 로그인을 차단하기 때문입니다.

2)하드웨어 관련 기능의 사용의 어려움

웹뷰에서 하드웨어 관련 기능(예: 카메라, GPS, 센서 등)을 사용하는 것도 브라우저에서와는 다르게 많은 제한이 따릅니다.

이러한 기능들은 네이티브 API와의 통합이 필요하며, 웹뷰 내에서 이를 구현하는 것은 복잡한 작업이 될 수 있습니다.

이 외에도 생각보다 크고 작은 부분이 웹뷰에서 브라우저와 차이가 나게 됩니다.


2.안드로이드 웹뷰와 기본 브라우저(크롬)의 차이점

1)기술적인 차이점과 엔진의 차이점

안드로이드 웹뷰와 크롬 브라우저는 모두 웹 콘텐츠를 렌더링하지만, 기술적인 차이점이 존재합니다.

웹뷰는 애플리케이션 내부에 삽입되는 뷰 컴포넌트로, 경량화된 형태로 제공되며 기본적으로 크로미움(Chromium) 엔진을 사용하지만, 크롬 브라우저는 완전한 기능을 갖춘 브라우저로 더 많은 기능과 최적화된 성능을 제공합니다.

2)브라우저에서는 되는데 왜 웹뷰에서는 안될까?

브라우저에서는 다양한 웹 표준과 최신 기능들이 지원되지만, 웹뷰는 이러한 기능들 중 일부를 지원하지 않을 수 있습니다.

이는 보안, 성능, 호환성 등의 이유로 인해 웹뷰가 제한된 기능을 제공하기 때문입니다.

3)웹뷰에서 안되는 것들은 무엇이 있을까?

기능설명브라우저 지원웹뷰 지원
소셜 로그인구글, 페이스북 등 소셜 로그인가능불가능
WebRTC실시간 통신 기능가능불가능
Service Workers오프라인 기능 및 푸시 알림가능불가능
클립보드 접근사용자의 클립보드에 접근하고 조작하는 기능가능불가능
WebGL3D 그래픽 렌더링가능제한적 지원
Notification API데스크톱 알림가능불가능
Background Sync백그라운드 동기화가능불가능
Geolocation API사용자의 위치 정보 접근가능제한적 지원
Navigator.share네이티브 공유 기능가능불가능
Payment Request API결제 요청 API가능불가능
File System Access API로컬 파일 시스템 접근가능불가능
Web Bluetooth API블루투스 장치와 통신가능불가능

4)웹뷰에서 안되는 것들을 되도록 하려면 어떻게 해야될까?

웹뷰에서 지원하지 않는 기능들을 사용하려면 커스텀 웹뷰를 구현하거나 네이티브 기능과의 연동을 통해 문제를 해결할 수 있습니다.

예제1: 클립보드 접근 구현하기

웹뷰에서는 기본적으로 클립보드 접근이 제한됩니다.

이를 해결하기 위해 네이티브 코드를 통해 클립보드 접근을 구현할 수 있습니다.

Android 예제 코드:

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;

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);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient());
        webView.addJavascriptInterface(new WebAppInterface(this), "AndroidClipboard");
        webView.loadUrl("file:///android_asset/index.html");
    }

    public class WebAppInterface {
        Context mContext;

        WebAppInterface(Context c) {
            mContext = c;
        }

        @JavascriptInterface
        public void copyToClipboard(String text) {
            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            ClipData clip = ClipData.newPlainText("copiedText", text);
            clipboard.setPrimaryClip(clip);
        }

        @JavascriptInterface
        public String getFromClipboard() {
            ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClip().getItemCount() > 0) {
                return clipboard.getPrimaryClip().getItemAt(0).getText().toString();
            } else {
                return "";
            }
        }
    }
}

웹 코드 예제:

<!DOCTYPE html>
<html>
<head>
    <title>Clipboard Example</title>
    <script>
        function copyText() {
            const text = document.getElementById("inputText").value;
            AndroidClipboard.copyToClipboard(text);
        }

        function pasteText() {
            const text = AndroidClipboard.getFromClipboard();
            document.getElementById("outputText").innerText = text;
        }
    </script>
</head>
<body>
    <h1>Clipboard Example</h1>
    <input type="text" id="inputText" placeholder="Enter text to copy">
    <button onclick="copyText()">Copy to Clipboard</button>
    <button onclick="pasteText()">Paste from Clipboard</button>
    <p id="outputText"></p>
</body>
</html>

웹뷰에서는 기본적으로 Navigator.share 기능이 지원되지 않습니다.

이를 해결하기 위해 네이티브 코드를 통해 공유 기능을 구현할 수 있습니다.

Android 예제 코드:

import android.content.Intent;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;

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);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient());
        webView.addJavascriptInterface(new WebAppInterface(this), "AndroidShare");
        webView.loadUrl("file:///android_asset/index.html");
    }

    public class WebAppInterface {
        Context mContext;

        WebAppInterface(Context c) {
            mContext = c;
        }

        @JavascriptInterface
        public void shareText(String text) {
            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_TEXT, text);
            sendIntent.setType("text/plain");
            Intent shareIntent = Intent.createChooser(sendIntent, null);
            startActivity(shareIntent);
        }
    }
}

웹 코드 예제:

<!DOCTYPE html>
<html>
<head>
    <title>Share Example</title>
    <script>
        function shareText() {
            const text = document.getElementById("inputText").value;
            AndroidShare.shareText(text);
        }
    </script>
</head>
<body>
    <h1>Share Example</h1>
    <input type="text" id="inputText" placeholder="Enter text to share">
    <button onclick="shareText()">Share Text</button>
</body>
</html>


3.브라우저 보다 웹뷰를 사용해야 하는 이유는? 웹뷰가 가진 장점

  • 1)가벼운 용량: 웹뷰는 애플리케이션의 일부로 포함되기 때문에 브라우저보다 가벼운 용량을 제공합니다.
  • 2)앱과의 통합: 웹뷰는 애플리케이션의 나머지 부분과 긴밀하게 통합될 수 있어, 일관된 사용자 경험을 제공할 수 있습니다.
  • 3)커스터마이징: 웹뷰는 개발자가 필요에 따라 커스터마이징할 수 있어 특정 요구사항에 맞출 수 있습니다.
  • 4)보안 제어: 웹뷰는 앱 내에서 특정 사이트나 콘텐츠만을 로드하도록 제어할 수 있어 보안 관리를 보다 엄격하게 할 수 있습니다.
  • 5)오프라인 기능: 웹뷰는 캐싱을 통해 오프라인에서도 일정 부분 기능을 사용할 수 있습니다.

네이티브 및 앱 제작 플랫폼을 사용할 동기가 적어지고 있습니다.

최신 웹 기술의 발전으로 많은 기능을 웹으로 구현할 수 있게 되어, 네이티브 앱 개발의 필요성이 줄어들고 있습니다.

개발 생산성과 멀티플랫폼 확장이 용이합니다.

웹 애플리케이션은 한 번 개발하면 다양한 플랫폼에서 사용할 수 있어 개발 생산성과 확장성이 높습니다.

위에서 언급한 많은 문제들은 스윙투앱을 사용하면 쉽게 해결할 수 있습니다.

웹 개발자들이 복잡한 네이티브 코드를 작성하지 않아도 손쉽게 앱을 만들 수 있도록 도와줍니다.

위의 안되는 것들의 대부분은 스윙투앱 웹뷰를 사용하면 구현이 가능합니다.

스윙투앱은 내장된 JavaScript API를 통해 네이티브 기능을 쉽게 사용할 수 있도록 지원합니다.

JavaScript API를 통해서 Native 기능을 쉽게 활용할 수 있습니다.

예를 들어, 로컬 스토리지, AdMob, 인앱 결제, 클립보드 등 다양한 네이티브 기능을 손쉽게 연동할 수 있습니다.


[스윙투앱 홈페이지]
http://www.swing2app.co.kr/
홈페이지 회원가입시 즉시 앱제작이 가능하며, 모두 무료로 이용할 수 있습니다 ^^

[스토어 유지보수 상담]
https://www.swing2app.co.kr/landing/storemt

[앱제작 가이드]
더많은 앱제작 관련 매뉴얼은 아래 도우미 사이트를 참고해주세요.
https://documentation.swing2app.co.kr/

[실시간 채팅 상담]
https://direct.lc.chat/12036120/

[문의 메일]
help@swing2app.co.kr

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다