본문 바로가기
Development/Android

[Android] Play Asset Delivery / Play Feature Delivery 완벽 가이드

by 은스타 2022. 9. 29.
반응형
Play Asset Delivery와 Play Feature Delivery 완벽 가이드: 대용량 안드로이드 앱 최적화하기

Play Asset Delivery와 Play Feature Delivery 완벽 가이드: 대용량 안드로이드 앱 최적화하기

개요

안녕하세요! 안드로이드 앱이 점점 더 복잡해지고 기능이 풍부해짐에 따라, 앱 크기는 지속적으로 증가하고 있습니다. 대형 게임이나 그래픽이 풍부한 앱의 경우 수 GB에 달하는 크기가 될 수 있죠.

구글은 이러한 문제를 해결하기 위해 Play Asset Delivery(PAD)와 Play Feature Delivery(PFD)라는 두 가지 강력한 기술을 제공합니다. 이 글에서는 두 기술의 개념부터 실제 구현 방법까지 상세히 알아보겠습니다.

목차
1. Play Asset Delivery와 Play Feature Delivery란?
2. 두 기술의 핵심 차이점
3. Play Asset Delivery 구현하기
4. Play Feature Delivery 구현하기
5. 자주 묻는 질문(FAQ)

#1. Play Asset Delivery와 Play Feature Delivery란?
두 기술 모두 안드로이드 앱 번들(Android App Bundle, AAB) 형식과 함께 작동하여 앱 배포를 최적화합니다.
1) Play Asset Delivery(PAD)
게임이나 대용량 앱의 에셋(이미지, 사운드, 비디오, 텍스처 등)을 효율적으로 전달하기 위한 시스템입니다. 사용자가 전체 앱을 다운로드하지 않고도 필요한 에셋만 다운로드할 수 있도록 합니다.
(1) PAD의 에셋 팩 유형
설치 시간(Install-time) 에셋 팩: 앱 설치 과정에서 함께 다운로드되는 에셋으로, 앱 실행 시 즉시 필요한 필수 에셋에 적합
빠른 팔로우(Fast-follow) 에셋 팩: 앱 설치 직후에 자동으로 다운로드되는 에셋으로, 초기 실행에는 필요하지 않지만 곧 필요하게 될 에셋에 적합
주문형(On-demand) 에셋 팩: 앱 내에서 특정 기능이나 레벨에 접근할 때만 다운로드되는 에셋으로, 게임의 후반 레벨이나 특정 상황에서만 필요한 에셋에 적합
(2) PAD의 주요 특징
텍스처 압축 형식 지원: 다양한 기기에 최적화된 텍스처 압축 형식을 자동으로 제공
전송 크기 절감: Brotli 압축 알고리즘을 사용하여 전송 크기를 최대 15% 절감
다운로드 진행 상황 모니터링: API를 통해 에셋 다운로드 진행 상황을 모니터링하고 사용자에게 표시 가능
단일 에셋 팩 최대 2GB: 대용량 에셋 관리 가능
. . . . .
2) Play Feature Delivery(PFD)
앱의 특정 기능 모듈을 필요할 때만 다운로드하여 설치할 수 있게 해주는 시스템입니다. 앱의 기본 모듈만 먼저 설치하고, 추가 기능은 사용자가 필요로 할 때 다운로드합니다.
(1) PFD의 동적 기능 모듈 유형
설치 시간(Install-time) 기능: 앱 설치 시 기본 모듈과 함께 다운로드되는 기능으로, 앱의 핵심 기능이지만 기본 모듈과 분리하고 싶을 때 사용
주문형(On-demand) 기능: 사용자가 특정 기능을 요청할 때만 다운로드되는 모듈로, 자주 사용되지 않는 기능(예: AR 기능, 특수 편집 도구)에 적합
조건부(Conditional) 기능: 특정 조건(국가, 기기 기능 등)에 따라 다운로드되는 모듈로, 특정 국가에서만 제공되는 기능이나 특정 하드웨어가 필요한 기능에 적합
(2) PFD의 주요 특징
동적 설치 관리: SplitInstallManager API를 통해 기능 모듈을 요청하고, 다운로드 상태를 모니터링하며, 필요 없는 모듈을 제거
코드 및 리소스 분리: 앱 코드와 리소스를 논리적인 기능 단위로 구성
인스턴트 앱 지원: 설치 없이 바로 실행 가능한 앱과 함께 작동
실행 가능한 코드 포함: 동적 기능 모듈에 Java/Kotlin 코드 포함 가능

#2. 두 기술의 핵심 차이점
Play Asset Delivery와 Play Feature Delivery는 서로 다른 목적과 구현 방식을 가지고 있습니다.
특성 Play Asset Delivery (PAD) Play Feature Delivery (PFD)
주요 목적 게임 에셋, 미디어 파일 등 리소스 전달 최적화 앱의 기능 모듈화 및 필요시 다운로드
대상 주로 게임 및 대용량 미디어 앱 모든 유형의 안드로이드 앱
다루는 내용 에셋(이미지, 사운드, 동영상, 3D 모델 등) 코드, 리소스, 에셋을 포함한 완전한 기능 모듈
구현 방식 AssetPackManager API Play Core 라이브러리의 SplitInstallManager API
코드 실행 에셋에는 실행 가능한 코드가 포함되지 않음 동적 기능 모듈에 실행 가능한 코드 포함 가능
크기 제한 단일 에셋 팩 최대 2GB 단일 기능 모듈 최대 64MB(인스턴트 앱 모드)
업데이트 앱 업데이트와 독립적으로 에셋 업데이트 가능 앱 업데이트를 통해 기능 모듈 업데이트
1) 선택 가이드
PAD를 선택해야 하는 경우
① 게임 개발자로 대용량 텍스처, 모델, 사운드 파일을 포함하는 경우
② 멀티미디어 앱으로 비디오, 오디오 등 대용량 미디어 파일을 포함하는 경우
③ 실행 코드 없이 리소스만 필요한 경우
④ 에셋 중심 앱으로 주요 내용이 에셋으로 구성된 경우
PFD를 선택해야 하는 경우
① 모듈화된 앱으로 독립적인 기능 단위로 구성된 경우
② 선택적 기능이 많아 사용자가 필요에 따라 선택할 수 있는 경우
③ 지역별 기능 제공이 필요한 경우
④ 코드와 리소스를 함께 포함한 기능 모듈이 필요한 경우

#3. Play Asset Delivery 구현하기
1) 프로젝트 설정
먼저 app/build.gradle 파일에 Play Core 라이브러리 종속성을 추가합니다:
dependencies {
    implementation 'com.google.android.play:core:1.10.3'
    implementation 'com.google.android.play:asset-delivery:2.0.0'
}
. . . . .
2) 에셋 팩 생성 및 구성
app/build.gradle 파일에 에셋 팩 구성을 추가합니다:
android {
    // 다른 설정들...

    assetPacks = [":game_level_1", ":game_level_2"]

    // 또는 더 상세한 구성을 위해:
    bundle {
        assetPacks {
            assets {
                packName = "game_level_1"
                deliveryType = "on-demand"
            }
            // 추가 에셋 팩 구성...
        }
    }
}
. . . . .
3) 에셋 팩 요청 및 로드
앱 코드에서 에셋 팩을 요청하고 로드하는 방법:
private AssetPackManager assetPackManager;

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

    // AssetPackManager 초기화
    assetPackManager = AssetPackManagerFactory.getInstance(this);

    // 에셋 팩 요청
    List<String> packNames = Arrays.asList("game_level_1");
    assetPackManager.fetch(packNames)
            .addOnSuccessListener(result -> {
                Log.d("PAD", "Asset pack download success");
                // 에셋에 접근
                loadAssets(packNames.get(0));
            })
            .addOnFailureListener(exception -> {
                Log.e("PAD", "Asset pack download failed: " + exception.getMessage());
            });
}

private void loadAssets(String packName) {
    try {
        // 에셋 팩 경로 가져오기
        AssetPackLocation packLocation = assetPackManager.getPackLocation(packName);
        if (packLocation != null) {
            String assetPath = packLocation.assetsPath();
            // 에셋 사용...
        }
    } catch (IOException e) {
        Log.e("PAD", "Error loading assets: " + e.getMessage());
    }
}
. . . . .
4) 다운로드 진행 상황 모니터링
private void registerPackStateListener() {
    AssetPackStateUpdateListener listener = state -> {
        switch (state.status()) {
            case AssetPackStatus.PENDING:
                // 다운로드 대기 중
                break;
            case AssetPackStatus.DOWNLOADING:
                // 다운로드 중
                long downloaded = state.bytesDownloaded();
                long total = state.totalBytesToDownload();
                int progress = (int) (100 * downloaded / total);
                updateProgressUI(progress);
                break;
            case AssetPackStatus.COMPLETED:
                // 다운로드 완료
                hideProgressUI();
                break;
        }
    };

    assetPackManager.registerListener(listener);
}

#4. Play Feature Delivery 구현하기
1) 프로젝트 설정
app/build.gradle 파일에 Play Core 라이브러리 종속성을 추가합니다:
dependencies {
    implementation 'com.google.android.play:core:1.10.3'
}
. . . . .
2) 동적 기능 모듈 생성
Android Studio에서 동적 기능 모듈을 생성하는 방법:

① File > New > New Module 선택
② Dynamic Feature Module 선택 후 Next 클릭
③ 모듈 이름, 패키지 이름 입력 및 모듈 옵션 선택
④ Finish 클릭
. . . . .
3) 동적 기능 요청 및 설치
private SplitInstallManager splitInstallManager;

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

    // SplitInstallManager 초기화
    splitInstallManager = SplitInstallManagerFactory.create(this);

    // 기능 모듈 요청 생성
    SplitInstallRequest request = SplitInstallRequest.newBuilder()
            .addModule("dynamic_feature_module_name")
            .build();

    // 기능 모듈 설치 요청
    splitInstallManager.startInstall(request)
            .addOnSuccessListener(sessionId -> {
                Log.d("PFD", "Module installation success");
                loadFeatureModule();
            })
            .addOnFailureListener(exception -> {
                Log.e("PFD", "Module installation failure: " + exception.getMessage());
            });
}
. . . . .
4) 설치 상태 모니터링
private void registerInstallListener() {
    SplitInstallStateUpdatedListener listener = state -> {
        switch (state.status()) {
            case SplitInstallSessionStatus.DOWNLOADING:
                // 다운로드 중
                long downloaded = state.bytesDownloaded();
                long total = state.totalBytesToDownload();
                int progress = (int) (100 * downloaded / total);
                updateProgressUI(progress);
                break;
            case SplitInstallSessionStatus.INSTALLED:
                // 설치 완료
                hideProgressUI();
                loadFeatureModule();
                break;
            case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION:
                // 큰 모듈(10MB 이상)은 사용자 확인 필요
                try {
                    splitInstallManager.startConfirmationDialogForResult(
                        state, activity, CONFIRMATION_REQUEST_CODE);
                } catch (IntentSender.SendIntentException e) {
                    Log.e("PFD", "Error launching confirmation dialog", e);
                }
                break;
        }
    };

    splitInstallManager.registerListener(listener);
}

#5. 자주 묻는 질문(FAQ)
1) Q: 두 기술 중 어떤 것을 선택해야 하나요?
A: 앱의 성격과 요구사항에 따라 다릅니다. 게임이나 대용량 미디어를 다루는 앱이라면 Play Asset Delivery가 적합하고, 기능별로 모듈화가 필요한 일반 앱이라면 Play Feature Delivery가 더 적합합니다. 두 기술을 함께 사용할 수도 있습니다.
. . . . .
2) Q: 모든 안드로이드 기기에서 지원되나요?
A: Android 5.0(API 레벨 21) 이상을 지원합니다. 단, 일부 기능은 더 높은 API 레벨이 필요할 수 있으며, 구글 플레이 스토어가 설치된 기기에서만 작동합니다.
. . . . .
3) Q: 앱 번들(App Bundle)과 어떤 관계가 있나요?
A: 두 기술 모두 Android App Bundle(AAB) 포맷을 기반으로 합니다. AAB는 구글 플레이 스토어가 각 기기에 최적화된 APK를 전달하는 데 사용되는 새로운 앱 배포 형식입니다. Play Asset Delivery와 Play Feature Delivery는 이 AAB 형식을 확장하여 더 세분화된 콘텐츠 전달을 가능하게 합니다.
. . . . .
4) Q: 에셋 팩과 동적 기능 모듈의 크기 제한은?
A: 크기 제한은 다음과 같습니다:

에셋 팩: 개별 에셋 팩은 최대 2GB까지 가능
동적 기능 모듈: 일반적으로 크기 제한이 없지만, 인스턴트 앱으로 제공하려면 10MB 이하로 유지. 10MB 이상인 모듈은 다운로드 시 사용자 확인 필요
. . . . .
5) Q: 앱 업데이트 시 모듈과 에셋도 업데이트해야 하나요?
A: 각 기술별로 다릅니다:

Play Asset Delivery: 에셋 팩은 앱 업데이트와 별개로 업데이트할 수 있으며, 구글 플레이는 변경된 에셋만 전송
Play Feature Delivery: 동적 기능 모듈은 앱 업데이트의 일부로 업데이트. 앱 버전이 변경되면 모듈도 함께 업데이트될 수 있음
. . . . .
6) Q: 오프라인 상태에서 작동하나요?
A: 이미 다운로드된 에셋 팩과 기능 모듈은 오프라인 상태에서도 사용 가능합니다. 그러나 아직 다운로드되지 않은 콘텐츠에 접근하려면 인터넷 연결이 필요합니다. 중요한 기능의 경우 오프라인 대체 경험을 제공하는 것이 좋습니다.
. . . . .
7) Q: 테스트는 어떻게 하나요?
A: 테스트 방법은 다음과 같습니다:

개발 중 테스트: 개발 모드에서 로컬 테스트 가능
배포 전 테스트: 구글 플레이 콘솔의 내부 테스트 트랙이나 테스트 기기 사용
테스트 API: Play Core 라이브러리는 에셋 팩과 기능 모듈을 테스트하기 위한 특별한 API 제공
. . . . .
8) Q: 보안은 어떻게 유지되나요?
A: 구글 플레이 스토어는 모든 에셋 팩과 기능 모듈이 원본 앱과 동일한 서명으로 서명되었는지 확인합니다. 또한 전송 중인 데이터는 암호화되어 안전하게 보호됩니다. 민감한 데이터가 포함된 모듈의 경우 추가 암호화 계층을 구현하는 것이 좋습니다.
. . . . .
9) Q: 두 기술을 함께 사용할 수 있나요?
A: 네, 가능합니다! 복잡한 앱에서는 두 기술을 함께 사용하여 최상의 결과를 얻을 수 있습니다. 기본 구조는 Play Feature Delivery로 모듈화하고, 각 모듈 내 대용량 에셋은 Play Asset Delivery로 관리하는 방식이 효과적입니다.

마무리
Play Asset Delivery와 Play Feature Delivery는 안드로이드 앱 개발의 미래를 대표하는 기술로, 앱 크기 최적화, 사용자 경험 개선, 그리고 더 효율적인 앱 배포를 가능하게 합니다.

핵심 요약:

PAD는 에셋 중심 - 게임이나 멀티미디어 앱의 대용량 리소스 관리에 최적
PFD는 기능 모듈 중심 - 앱의 기능을 독립적으로 배포하고 관리
초기 다운로드 크기 대폭 감소 - 사용자 경험 개선 및 설치율 향상
필요한 것만 다운로드 - 저장 공간 절약 및 데이터 사용량 감소
두 기술 병행 사용 가능 - 복잡한 앱에서 최대 효과

앱의 특성과 요구사항에 맞는 기술을 선택하거나 함께 활용하여 더 나은 안드로이드 앱 경험을 제공하시기 바랍니다.
긴 글 읽어주셔서 감사합니다.

끝.
반응형