간단히 답하면: 네, Google Play는 인터프리트되는 code의 라이브 업데이트를 허용합니다. 새로운 Play Store 심사 없이 Android 앱에 새 JavaScript, HTML, CSS를 푸시할 수 있습니다. dex, JAR 또는 이와 같은 네이티브 code는 다운로드할 수 없습니다. .so 파일.
이 부분은 Apple보다 Google이 더 명확합니다. WebView 내 JavaScript에 대한 예외 조항이 정책에 직접 명시되어 있기 때문입니다. 이 페이지에서는 해당 조항을 인용하고, 경계가 어디인지 보여주며, Google이 이를 어떻게 집행하는지 설명합니다.
이 내용은 법적 조언이 아닙니다. 현재 정책 문구와 수천 개 앱이 프로덕션에서 이 정책을 어떻게 활용하는지 설명합니다.
Google Play 정책의 실제 내용
해당 규정은 기기 및 네트워크 남용 정책에 명시되어 있습니다:
Google Play를 통해 배포되는 앱은 Google Play의 업데이트 메커니즘 이외의 방법으로 앱을 수정, 교체 또는 업데이트할 수 없습니다. 마찬가지로 앱은 Google Play 이외의 소스에서 실행 가능한 code(예: dex, JAR, .so 파일)를 다운로드할 수 없습니다. 이 제한은 가상 머신이나 인터프리터에서 실행되며, 둘 중 하나가 Android API에 간접적으로 접근할 수 있게 하는 code(예: webview 또는 브라우저의 JavaScript)에는 적용되지 않습니다.
그리고 바로 이어서:
런타임에 로드되는(예: 앱에 패키징되지 않은) 인터프리터 언어(JavaScript, Python, Lua 등)를 사용하는 앱이나 SDK 같은 제3자 code는 잠재적인 Google Play 정책 위반을 허용해서는 안 됩니다.
즉, 두 가지 규칙이 있습니다:
- Native code는 Google Play에서만 제공됩니다. 다운로드된 dex, JAR 또는 네이티브 라이브러리는 허용되지 않습니다.
- 인터프리터 방식의 code는 어디서든 가져올 수 있지만, 그 동작은 여전히 모든 Play 정책을 준수해야 합니다.
Capacitor 앱의 웹 레이어는 Android WebView에서 실행되는 JavaScript, HTML, CSS로, Google이 바로 이 예를 듭니다. 이는 면제 대상에 해당합니다.
허용 기준
| live update 사용 시 허용 | live update 사용 시 허용 안 됨 |
|---|---|
| JavaScript, HTML, CSS 버그 수정 | dex, JAR, APK 또는 .so 파일 다운로드 |
| 기존 웹 스택의 UI 변경, 문구 변경, 새 화면 추가 | Google Play 업데이트 메커니즘 밖에서 앱을 교체하는 행위 |
| 웹 code의 A/B 테스트 및 단계적 출시 | Play 정책을 위반하는 code 배포 (기만적 동작, 악성코드, 정책 위반 콘텐츠) |
| 이미지, 번역, 설정 업데이트 | 스토어 설명과 다른 앱으로 바뀌는 경우 |
| 잘못된 릴리스를 롤백하는 경우 | Android 권한이나 보안을 우회하는 경우 |
Capgo은 왼쪽 열의 내용만 배포합니다. 새로운 Capacitor 플러그인이나 새로운 권한, AndroidManifest.xml또는 Gradle 의존성 같은 네이티브 요소는 여전히 Google Play를 통한 새 릴리스가 필요합니다. Capgo은 버전 타겟팅 새로운 네이티브 code이 필요한 번들을 기존 바이너리와 분리해 관리합니다.
Google의 규제 방식
Google은 앱이 다운로드한 실행 가능한 code이 있는지, 설치 후 동작이 변하는지 스캔합니다. 자동화된 체크는 APK 외부에서 dex 또는 네이티브 라이브러리를 로드하는지 확인하며, WebView 내의 JavaScript는 이에 해당하지 않습니다.
진짜 위험은 두 번째 규칙입니다. live update 때문에 앱이 Play 정책이 금지하는 동작을 하게 되면, code이 어떤 방식으로 전달되었든 위반입니다. 기만적 행위 정책은 심사 후 기능이 바뀌는 앱에도 적용됩니다.
실제 사례:
- 출시한 앱의 버그 수정과 개선에는 라이브 업데이트를 사용하세요.
- Play Store 스토어 등록정보 및 데이터 보안 양식과 앱을 일관되게 유지하세요.
- 네이티브 변경 사항과 대규모 출시는 Google Play를 통해 배포하되, 단계적 배포 점진적인 배포를 원한다면,
어떤 스택이 Android에서 이를 지원할까요?
Android에서 OTA 업데이트를 배포할 수 있는지는 한 가지 질문에 달려 있습니다. 앱 로직이 런타임에 인터프리트되나요? JavaScript와 기타 인터프리트되는 code는 가능합니다. 다운로드한 dex, JAR, 네이티브 .so 파일은 불가능합니다. Flutter처럼 AOT 컴파일되는 프레임워크는 VM이나 인터프리터를 통해서만 가능합니다.
스택별 Android live update 호환성
| 스택 | Android에서 code이 실행되는 방식 | Live updates 허용 여부 | 도구 |
|---|---|---|---|
| Capacitor | Android WebView 내의 JavaScript, HTML, CSS | 지원 | Capgo |
| Ionic (Capacitor 기반) | Capacitor와 동일 | 지원 | Capgo |
| Cordova | Android WebView 내의 JavaScript | 지원 | Capacitor로 마이그레이션한 후의 Capgo, 레거시 Cordova 플러그인 |
| React Native / Expo | Hermes 기반 JavaScript bundle | 네, JavaScript만 지원 | Expo Updates, 자체 호스팅 CodePush 대안 |
| NativeScript | V8 기반 JavaScript | 네, JavaScript만 지원 | 제한적, 주로 자체 구축 방식 |
| Flutter | 네이티브 라이브러리로 AOT 컴파일된 Dart | VM 또는 인터프리터를 통해서만 가능 | Shorebird |
| Native Kotlin / Java | ART 상의 dex bytecode | Native code는 불가, WebView 내 JavaScript는 가능 | 원격 구성(Remote config), Play Feature Delivery |
| Kotlin / Compose Multiplatform | ART 상의 dex bytecode | 아니요 | 원격 구성(Remote config), Play Feature Delivery |
| .NET MAUI / Xamarin | APK에 포함된 .NET runtime 및 native libraries | 아니요 | 원격 구성만 사용 |
| Unity / Unreal | IL2CPP 또는 C++로 컴파일된 C# | code는 안 되지만, 콘텐츠는 가능합니다 | Asset bundles, Play Asset Delivery, 스크립트 콘텐츠 (Lua) |
| Web wrapper / TWA | WebView 또는 Chrome에서 로드되는 웹사이트 | 항상 라이브 상태 | 필요 없음 |
Capacitor, Ionic 및 Cordova: 완벽히 지원
UI와 비즈니스 로직이 Android WebView에서 실행되는 JavaScript인 경우, 이는 Google 정책에서 허용하는 code의 정확한 예시입니다. live update은 웹 번들을 교체하지만, APK, native plugins 및 권한은 기존에 게시한 상태를 유지합니다.
Capgo는 웹 레이어만 변경할 수 있기 때문에 설계상 규정을 준수합니다. 새로운 네이티브 플러그인, 새로운 권한, AndroidManifest.xml Gradle 의존성 변경은 여전히 Google Play 릴리스가 필요합니다.
React Native 및 Expo: JavaScript는 가능, 네이티브 모듈은 불가
React Native는 Hermes에서 JavaScript bundle을 실행하며, 이는 인터프리트되는 code로 간주됩니다. Expo Updates와 현재는 종료된 Microsoft CodePush가 해당 bundle을 업데이트합니다. CodePush를 떠나는 팀은 대체 수단이 필요합니다. 네이티브 모듈과 React Native 업그레이드는 새 릴리스가 필요합니다.
Flutter: VM 또는 인터프리터를 통해서만 가능
Flutter는 Dart를 AOT 컴파일하여 libapp.so로 만듭니다. 새로운 .so 를 다운로드하는 것은 명시적으로 금지되어 있으므로, 기본 Flutter는 live updates를 사용할 수 없습니다. Shorebird는 code push를 추가하며, Dart 가상 머신을 통해 업데이트를 실행하여 Play 정책을 준수한다고 밝힙니다. 자세한 내용은 Flutter 앱용 live updates.
네이티브 Kotlin, Java 및 Kotlin Multiplatform: code 업데이트 불가
dex 또는 JAR 파일을 다음 방식으로 로드하는 것은 DexClassLoader 정책에서 금지하는 정확한 동작입니다. Google의 자체 대안은 Play Feature Delivery이며, 이는 Google Play를 통해 code 모듈을 다운로드합니다. 그렇지 않으면 네이티브 code를 변경할 수 없습니다. WebView에서 JavaScript를 실행하는 Kotlin 또는 Java 앱은 해당 code를 여전히 업데이트할 수 있는데, 이는 정책이 인터프리터 방식의 code를 예외로 두기 때문입니다. 그 외의 네이티브 로직은 원격 구성(remote config), 피처 플래그(feature flags), 서버 주도 UI(server-driven UI)로 제한됩니다.
Unity 및 게임 엔진: 콘텐츠는 가능, code는 불가
게임 code는 컴파일됩니다. 에셋 번들과 Play Asset Delivery가 콘텐츠를 처리하며, Lua와 같은 임베디드 스크립팅 언어는 인터프리터 방식의 code로 동작하며, 결과물이 Play 정책을 준수하는 한 정책상 허용됩니다.
웹 래퍼와 Trusted Web Activities: 라이브 업데이트가 기본
Trusted Web Activity 또는 WebView 래퍼가 웹사이트를 로드하므로 배포할 때마다 업데이트됩니다. Google Play는 TWA를 허용합니다. 오프라인 캐싱과 네이티브 브릿지는 해당 래퍼의 구현 방식에 따라 달라집니다. TWA는 PWA 서비스 워커를 사용할 수 있고, WebView 셸은 직접 구축한 JavaScript 브릿지를 노출할 수 있습니다. 번들링된 Capacitor 앱은 APK에 웹 번들을 포함하며, 라이브 업데이트를 위한 일관된 플러그인 레이어를 추가합니다.
Android에서 그 어떤 스택도 구현할 수 없는 것
어떤 프레임워크를 쓰든 live update로는 다음을 할 수 없습니다:
- dex, JAR, APK 또는 네이티브 파일을
.soGoogle Play 외부에서 다운로드 - 새로운 Android 권한 추가
- Google Play 정책에서 금지하는 기능 수행
- Play Store 스토어 정보와 다른 앱으로 변경
다음 단계
- iOS의 답변: Apple은 App Store 심사 없이 Live Update를 허용하나요?
- 준수 사항 체크리스트: Google Play OTA 준수 체크리스트
- 배포 전략: Google Play 준수: 주요 업데이트 전략
심사 대기 없이 오늘 바로 수정 사항 배포
Capgo Live Update 사용하기 채널, 롤백, 델타 업데이트 및 종단간 암호화를 통해 JavaScript, HTML, CSS 변경 사항을 몇 분 만에 Capacitor 앱에 푸시하세요. 오픈 소스이며 셀프 호스팅이 가능합니다.
bunx @capgo/cli@latest init
다음 퀵스타트 첫 업데이트를 전송하려면.