λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

κ³³κ°„μ—μ„œ μΈμ‹¬λ‚œλ‹€/싀무

[Android]μ•± λΉŒλ“œ μ„€μ • - zero base ν”„λ‘œμ νŠΈ 개발 μ‹œ λ‚΄μš© μ •λ¦¬μ˜ ν•„μš”μ„±μ„ λŠλ‚€ 것듀

μ°Έκ³  

 

λ¬Έμ„œ μž‘μ„± ν•„μš”μ„±

κΈ‰ν•˜κ²Œ zero base ν”„λ‘œμ νŠΈλ₯Ό λ„˜κ²¨λ°›μ•„μ„œ 일을 ν–ˆμ—ˆμŒ.

이것 저것 λΉŒλ“œ κ΄€λ ¨ν•΄μ„œ μ„€μ • ν•΄μ•Όν•˜λŠ” 건 μ•„λŠ”λ° ꡬ체적인 방법듀은 ν™•μ‹€ν•˜κ²Œ 생각이 λ‚˜μ§€ μ•Šμ•„ λ‹€ κ²€μƒ‰ν•˜λ©° μ°Ύμ•„μ•Ό ν–ˆμŒ.

μ΄λ²ˆμ— μ •λ¦¬ν•΄μ„œ λ‹€μŒ λ²ˆμ— λˆ„λ½ 사항 없이, 덜 ν—€λ§€λ©΄μ„œ λΉ λ₯΄κ²Œ μž‘μ—…ν•˜κΈ° μœ„ν•΄ 기둝함.

 

기둝 λŒ€μƒ   

  • apk, aab 파일 이름 μžλ™ 생성
  • flavor/type 별 μ„€μ •
  • flavor/type 별 사이닝 ν‚€ μžλ™ μ„€μ •
  • flavor/type 별 μ•± 이름 μžλ™ μ„€μ •
  • 릴리즈 버전 μ„€μ •
  • buildFeatures μ˜΅μ…˜ κ°’λ“€

πŸ€” μΆ”κ°€ν•  것듀이 더 μžˆμœΌλ €λ‚˜...

 

app λͺ¨λ“ˆ build.gralde.kts 파일

val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(rootProject.file("keystore.properties")))
android {
    ...
    
    defaultConfig {
        ...
        versionCode = //버전 μ½”λ“œ κ°’
        versionName = //버전 λ„€μž„ κ°’
        ...
    
        // λΉŒλ“œ μ‚°μΆœλ¬Ό apk, aab의 이름 μ„€μ •
        // λ‚˜λŠ” 버전 λ„€μž„, 버전 μ½”λ“œ 값을 λ„£λŠ” κ±Έ μ„ ν˜Έν•¨.
        // μ΄λ ‡κ²Œ μ„€μ •ν•œ 이름 뒀에 λΉŒλ“œ νƒ€μž…κ°’μ΄ μžλ™μœΌλ‘œ λΆ™λŠ”λ‹€.
        // 예) MyApp-1.0(10)-productionRelease.apk
        setProperty(
            "archivesBaseName",
            "{앱이름}-$versionName($versionCode)"
        )
    }
    
    // ν‚€ 사이닝 μ„€μ •
    // keysotre.properties 파일 μ•ˆμ— ν•΄λ‹Ή key, value 값듀이 μ„€μ •λ˜μ–΄ μžˆλŠ” μƒνƒœ
    signingConfigs {
        create("developeKey") {
            storeFile = file(keystoreProperties["developeStoreFile"] as String)
            storePassword = keystoreProperties["developeStorePassword"] as String
            keyAlias = keystoreProperties["developeKeyAlias"] as String
            keyPassword = keystoreProperties["developeKeyPassword"] as String
        }
        create("productionKey") {
            storeFile = file(keystoreProperties["productionStoreFile"] as String)
            storePassword = keystoreProperties["productionStorePassword"] as String
            keyAlias = keystoreProperties["productionKeyAlias"] as String
            keyPassword = keystoreProperties["productionKeyPassword"] as String
        }
    }
    
    flavorDimensions += "server"
    productFlavors {
        create("develope") {
            dimension = "server"
            applicationIdSuffix = ".dev"
            //사이닝킀 μ„€μ •
            signingConfig = signingConfigs.getByName("developeKey")
            // develope νƒ€μž…μœΌλ‘œ λΉŒλ“œλ  경우 μ•± 이름 μ„€μ •
            // 이 appName은 AndroidManifest.xml νŒŒμΌμ—μ„œ <application> μ•ˆμ˜ 
            // android:label="{appName}"으둜 쓰인닀.
            manifestPlaceholders["appName"] = "@string/app_name_dev"
        }
        create("production") {
            dimension = "server"
            signingConfig = signingConfigs.getByName("productionKey")
            manifestPlaceholders["appName"] = "@string/app_name"
        }
    }

    buildTypes {
        release {
            isDebuggable = false
            isMinifyEnabled = true // R8 μ‹€ν–‰
            // R8은 λ‚œλ…ν™”μ— ν”„λ‘œκ°€λ“œ 룰을 μ“΄λ‹€.
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    
    buildFeatures {
        compose = true // ν•„μš” μ‹œ
        buildConfig = true // ν•„μš” μ‹œ
        viewBinding = true // ν•„μš” μ‹œ
        dataBinding = true // ν•„μš” μ‹œ
    }
    
    ...
}