봄날은 갔다. 이제 그 정신으로 공부하자

낡아버린 박스처럼 이제는 추억이되어 버린 Release빌드 본문

잡썰

낡아버린 박스처럼 이제는 추억이되어 버린 Release빌드

길재의 그 정신으로 공부하자 2020. 11. 27. 16:47

Google Play Store에서 app bundle 배포방식을 권장하면서 마켓에 배포되는 많은 앱들이 하나둘씩 app bundle로 배포를 전환하면서 이제 대부분의 앱들이 app bundle 방식으로 Google Play Store에 등록 된다고 해도 무방할 듯 합니다.

Google Play Store에서 내년 하반기(2021년)부터는 무조건 app bundle 방식으로 배포해야 한다고 하니 apk 배포하는 개발사들은 빨리 배포 방식을 전환하는 것이 좋습니다.

 

apk에서 app bundle로 배포하는데 문제는 없을까?

저는 Google Play Store에 apk 방식으로 앱을 릴리즈해서 배포하고 있습니다. app bundle로 배포하는데 문제가 없을까요?

많은 개발자들이 이와 같은 걱정을 할거라고 생각합니다. 

 

저도 app bundle 최초 배포할때 "이거 정말 되는거 맞아?", "괜히 이거 배포했다가 apk 파일이랑 충돌 생겨서 앱 내려가는거 아냐?" 등등 많은 걱정을 했습니다.

 

특히 걱정이 정점을 찍은 사건이 앱 사이닝키를 마켓에 등록할 때...

아~~ 이거 불안한데... 라는 마음을 감출 수가 없었지요.

 

걱정할 필요 없습니다.

사이닝 잘 되고 배포 잘 됩니다. (오히려 사이닝키를 별도로 관리하지 않아도 되서 더 편해졌습니다.)

걱정되는 분들은 app bundle 최초 배포 시 베타 버전 배포를 우선해서 충분히 테스트한 후 상용 배포 하시면 됩니다.

 

그리고 app bundle로 배포하면 app 사이즈가 조금 줄어 듭니다.

정확히 기억이 나지는 않지만 저는 대략 3% 미만으로 사이즈가 줄어든 것 같네요.

 

app bundle 관련된 내용을 조금 더 자세히 적으면 좋겠지만 이글을 작성한 목적이 Release 빌드와 관련된 내용이므로 여기까지만 하겠습니다.

 

그럼에도 불구하고 아직은 Release 빌드가 필요합니다.

제 개인적인 생각이지만 제목처럼 Android app 개발에서 Release 빌드는 낡아버린 박스이지만 아직은 필요한 방식이라고 생각됩니다.

모든 사용자들이 마켓에서 앱을 다운로드 받으면 좋겠지만 조건이 맞지 않아 마켓에서 앱을 다운로드 받을 수 없는 사용자도 간혹 존재합니다. (믿을 수 없겠지만 실제로 그렇습니다.) 이러한 사용자들에게 사이닝도 안된 개발용 debug app을 전달할 수는 없어 앱 빌드 시 항상 app bundle과 함께 Release apk를 같이 만들어 별도로 관리하다가 요구사항이 발생하는 경우, Release apk를 전달합니다.

 

개발자 중에 간혹, 편법으로 app bundle로 등록된 앱을 Google Play Store에서 다운로드 받아서 다른 사용자에게 전달하는 꼼수를 사용하는 경우도 있는데 이거는 하시면 안됩니다.

app bundle로 Google Play Store에 등록된 앱은 사용자가 다운로드 선택 시 사용자의 단말 환경에 맞게 apk를 빌드해서 내려주기 때문에 전달 받은 단말 환경(해상도, 언어, ...)이 다운로드 단말과 다른 경우, 오동작할 수 있습니다.

 

Release 빌드 환경 구축

app 레벨의 build.gradle 파일에 아래와 같이 사이닝키 파일 위치를 지정해주고 패스워드를 포함한 필요 정보를 추가합니다.

signingConfigs{
        release{
            storeFile file('./../../signingkey/mykey.keystore')
            storePassword "00000000"
            keyAlias "mykey"
            keyPassword 00000000"
        }
    }

 

아래 부분에 release build type을 추가합니다.

buildTypes {
   debug {
      multiDexEnabled true
      minifyEnabled false
   }
   release {
      multiDexEnabled true
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
      signingConfig signingConfigs.release
      applicationVariants.all { variant ->
         renameAPK(variant)
      }
   }
}

Release apk를 그냥 만들면 build의 release 폴더에 app-release.apk 이런식으로 파일이 생성됩니다.

이렇게 생성된 파일명은 이쁘지 않으므로 renameAPK() 함수를 사용해서 파일명을 바꾸어줍니다.

def renameAPK(variant) {
    variant.outputs.all { output ->
        def formattedDate = new Date().format('yyyyMMdd')
        def versionCode = variant.versionCode
        outputFileName = "myapp_vc${versionCode}_${formattedDate}.apk"
    }
}

이렇게 하는 경우 빌드된 파일이름이 app name + 버전코드 + 생성년월일 .apk로 생성되기 때문에 알아보기 편합니다.

 

젠장 Proguard!!

릴리즈 빌드 해본 개발자들은 한번쯤 경험해보았을 상황이 개발에서는 잘 되다가 마켓에 배포했더니 앱이 오동작을 하더라 입니다. 이 경우 100% 난독화하면서 발생한 문제 입니다.

아래 옵션들만 기억하면 난독화는 쉽습니다.

-keep class io.reactivex.** { *; }

경로가 io.reactivex. 하위에 존재하는 모든 class를 난독화 하지 마라 입니다.

세부 옵션이 있지만 생략... (이제는 추억이니까... 굳이 세부 옵션 설명은 필요 없을 듯 합니다.)

-dontshrink
-dontoptimize

사용하지 않는 함수 및 최적화를 하지 마라 입니다.

난독화시 사용하지 않는다고 생각해서 함수를 삭제하는데 이게 잘못된 경우가 있습니다.

위의 -keep class로 안되는 경우, 해당 옵션을 추가하면 대부분 해결됩니다.

옵션 유무에 따라 생성된 apk 사이즈가 많게는 20%정도 차이나므로 무조건 추가하기 보다는 안되는 경우에만 추가하는것이 좋습니다.

-keepattributes Signature
-keepattributes Annotation

signature와 Annotation을 난독화 하지마라 입니다.

 

빌드 중 난독화 관련 warning이 발생하는 경우 아래 코드를 추가해주면 됩니다.

-dontwarn javax.annotation.Nullable

 

이러한 과정을 거쳐 release apk가 생성되면 build 폴더에 mapping이라는 폴더가 한개 생기는데 여기를 확인하시면 3개의 파일(mapping.txt, seeds.txt, usage.txt)이 있습니다. 이 파일들은 난독화된 앱을 다시 정상으로 돌려서 디버깅하는데 사용하는 파일로 release apk를 Google Play Store에 배포하는 개발자라면 반드시 같이 등록해주어야 하는 파일 입니다.

그렇지 않은 경우, 에러 로그가 난독화되서 보여집니다. ㅠ_ㅠ

 

 

Release apk는 10년이 넘은 낡아버린 박스이지만 아직은 내용물을 담아 놓을 수 있는 것 같아 글을 작성해보았습니다.

 

그럼 저는 이만...

Comments