수색…


소개

Gradle은 개발자가 컴파일 및 응용 프로그램 제작 프로세스를 자동화하는 데 사용할 수있는 고급 스크립트를 작성할 수있게 해주는 JVM 기반의 빌드 시스템입니다. 이것은 유연한 플러그인 기반 시스템으로, 빌드 프로세스의 다양한 측면을 자동화 할 수 있습니다. .jar 컴파일 및 서명, 외부 종속성 다운로드 및 관리, AndroidManifest 필드 주입 또는 특정 SDK 버전 활용 등이 포함됩니다.

통사론

  • apply plugin : 정상적으로 사용되어야하는 플러그인은 'com.android.application' 또는 'com.android.library' 입니다.

  • android : 앱의 기본 구성

    • compileSdkVersion : 컴파일 SDK 버전
    • buildToolsVersion : 빌드 도구 버전
    • defaultConfig : 기본 설정으로 맛과 빌드 유형으로 덮어 쓸 수 있습니다.
      • applicationId : 예를 들어 PlayStore에서 사용하는 응용 프로그램 ID는 패키지 이름과 거의 동일합니다.
      • minSdkVersion : 필요한 최소 SDK 버전
      • targetSdkVersion : 컴파일하는 SDK 버전 (항상 최신 버전이어야 함)
      • versionCode : 각 업데이트에서 더 커야하는 내부 버전 번호
      • versionName : 사용자가 앱 세부 정보 페이지에서 볼 수있는 버전 번호
    • buildTypes : 다른 곳 (TODO)보기
  • dependencies : 앱의 maven 또는 local 의존성

    • 단일 종속성 compile
    • testCompile : 유닛 또는 통합 테스트에 대한 종속성

비고

또한보십시오

Android 용 Gradle - 확장 설명서 :

안드로이드에서 gradle의 사용에 대한 더 많은 주제와 예제를 찾을 수있는 또 다른 태그가 있습니다.
http://www.riptinar.com/topic/2092

기본 build.gradle 파일

이것은 모듈의 기본 build.gradle 파일의 예제입니다.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.3'

    signingConfigs {
        applicationName {
            keyAlias 'applicationName'
            keyPassword 'password'
            storeFile file('../key/applicationName.jks')
            storePassword 'keystorePassword'
        }
    }
    defaultConfig {
        applicationId 'com.company.applicationName'
        minSdkVersion 14
        targetSdkVersion 25
        versionCode 1
        versionName '1.0'
        signingConfig signingConfigs.applicationName
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'

    testCompile 'junit:junit:4.12'
}

DSL (도메인 특정 언어)

위 파일의 각 블록을 DSL (도메인 특정 언어)이라고합니다.


플러그인

첫 번째 apply plugin: 'com.android.application' 은 Gradle 용 Android 플러그인을 빌드에 적용하고 android {} 블록을 사용하여 Android 관련 빌드 옵션을 선언 할 수있게합니다.

Android 애플리케이션의 경우 :

apply plugin: 'com.android.application'

Android 라이브러리의 경우 :

apply plugin: 'com.android.library'

위의 샘플 에서 DSL 이해하기

두 번째 부분 인 android {...} 블록은 프로젝트에 대한 정보가 포함 된 Android DSL 입니다.

예를 들어, Android API 레벨을 지정하는 compileSdkVersion 을 설정할 수 있습니다.이 레벨은 Gradle에서 앱을 컴파일하는 데 사용해야합니다.
하위 블록 defaultConfig 에는 매니페스트의 기본값이 있습니다. Product Flavors로이를 override 할 수 있습니다.

다음 예에서 자세한 정보를 찾을 수 있습니다.


종속성

dependencies 블록은 android 블록 {...} 외부에 정의됩니다. 즉, Android 플러그인에 의해 정의되지는 않지만 표준 Gradle입니다.
dependencies 블록은 앱에 포함시키려는 외부 라이브러리 (일반적으로 Android 라이브러리이지만 Java 라이브러리도 유효)를 지정합니다. Gradle은 이러한 종속성을 자동으로 다운로드합니다 (사용 가능한 로컬 사본이없는 경우). 다른 라이브러리를 추가하려는 경우 비슷한 compile 라인을 추가하기 만하면됩니다.

여기에있는 줄 중 하나를 살펴 보겠습니다.

compile 'com.android.support:design:25.3.1'

이 줄은 기본적으로

안드로이드 지원 디자인 라이브러리에 대한 의존성을 프로젝트에 추가하십시오.

Gradle은 라이브러리를 다운로드하여 앱에서 사용할 수 있도록 표시하고 해당 코드도 앱에 포함됩니다.

Maven에 익숙하다면이 구문은 GroupId , 콜론, ArtifactId , 다른 콜론, 포함 할 종속성의 버전으로 버전 관리를 완전히 제어 할 수 있습니다.

플러스 (+) 기호를 사용하여 이슈 버전을 지정할 수는 있지만 가장 좋은 방법은 그렇게하지 않는 것입니다. 라이브러리가 사용자의 지식없이 변경 내용을 업데이트하여 업데이트되는 경우 문제가 발생할 수 있으며 이로 인해 앱에 충돌이 발생할 수 있습니다.

다른 종류의 의존성을 추가 할 수 있습니다.

aar flat dependencies에 특히주의를 기울여야합니다.

자세한 내용은 이 항목을 참조하십시오 .

appcompat-v7-v7에 대한 참고 사항

compile 'com.android.support:appcompat-v7:25.3.1'

이것은 단순히이 라이브러리 ( appcompat )가 Android API 레벨 7 이상과 호환된다는 것을 의미합니다.

junit 에 대한 참고 사항 : junit : 4.12

이것은 단위 테스트의 테스트 종속성입니다.


다른 빌드 구성과 관련된 종속성 지정

특정 빌드 구성 에만 종속성을 사용 debugCompile testCompile 하거나 일반 compile 대신 debugCompile , testCompile 또는 releaseCompile 을 사용하여 빌드 유형 또는 제품 특성 (예 : 디버그, 테스트 또는 릴리스)에 대해 서로 다른 종속성을 정의 하도록 지정할 수 있습니다 .

이는 릴리스 빌드에서 테스트 및 디버그 관련 종속성을 유지하는 데 유용하며 릴리스 APK 최대한 슬림하게 유지하고 디버그 정보를 사용하여 앱에 대한 내부 정보를 얻을 수 없도록 보장합니다.


signingConfig

signingConfig 사용하면 keystore 정보를 포함하도록 Gradle을 구성하고 이러한 구성을 사용하여 생성 된 APK가 서명되어 Play 스토어 출시 준비가되었는지 확인할 수 있습니다.

여기에서 헌신적 인 주제를 찾을 수 있습니다.

참고 : Gradle 파일에 서명 자격 증명을 보관하는 것은 좋지 않습니다. 서명 구성을 제거하려면 signingConfigs 부분 만 생략하면됩니다.
다른 방법으로 지정할 수 있습니다.

자세한 내용은이 항목을 참조하십시오. 키 저장소 비밀번호를 노출하지 않고 APK에 서명 하십시오.


헌신적 인 Gradle 주제 에서 Android 용 Gradle에 대한 자세한 정보를 확인할 수 있습니다 .

제품의 맛을 정의

제품의 맛 은 아래 보이는 것처럼 android { ... } 블록 안에있는 build.gradle 파일에 정의되어 있습니다.

...
android {
    ...
    productFlavors {
        free {
            applicationId "com.example.app.free"
            versionName "1.0-free"
        }
        paid {
            applicationId "com.example.app.paid"
            versionName "1.0-paid"
        }
    }
}

이렇게하면 freepaid 라는 두 가지 추가 제품 맛이 있습니다. 각각은 고유의 특정 구성 및 속성을 가질 수 있습니다. 예를 들어, 새로운 두 가지 맛은 기존의 main 맛과는 별도의 applicationIdversionName 집니다 (기본적으로 사용할 수 있으므로 여기에 표시되지 않음).

제품 풍미 특정 종속성 추가

특정 빌드 환경에 추가 할 수있는 방식과 유사하게 특정 제품 의 특성에 대한 종속성을 추가 할 수 있습니다.

이 예에서는 freepaid 라는 두 가지 제품 맛을 이미 정의했다고 가정합니다. 여기 을 정의하는 데 더 많은 부분이 있습니다 .
그런 다음 free 풍미에 대한 AdMob 종속성을 추가하고 paid 대한 Picasso 라이브러리를 추가 할 수 있습니다.

android {
    ...

    productFlavors {
        free {
            applicationId "com.example.app.free"
            versionName "1.0-free"
        }
        paid {
            applicationId "com.example.app.paid"
            versionName "1.0-paid"
        }
    }
}

...
dependencies {
    ...
    // Add AdMob only for free flavor
    freeCompile 'com.android.support:appcompat-v7:23.1.1'
    freeCompile 'com.google.android.gms:play-services-ads:8.4.0'
    freeCompile 'com.android.support:support-v4:23.1.1'

    // Add picasso only for paid flavor
    paidCompile 'com.squareup.picasso:picasso:2.5.2'
} 
...

제품 풍미 별 리소스 추가

특정한 제품 풍미를 위해 자원을 추가 할 수 있습니다.

이 예에서는 freepaid 라는 두 가지 제품 맛을 이미 정의했다고 가정합니다. 제품 풍미 별 리소스를 추가하기 위해 main/res 폴더와 함께 추가 리소스 폴더를 생성합니다. 그런 다음 리소스를 평소와 같이 추가 할 수 있습니다. 이 예에서는 각 제품 풍미에 대한 문자열 status 정의합니다.

/ src / main /res/values/strings.xml

<resources>
    <string name="status">Default</string>
</resources>

/ src / free /res/values/strings.xml

<resources>
    <string name="status">Free</string>
</resources>

/ src / paid /res/values/strings.xml

<resources>
    <string name="status">Paid</string>
</resources>

제품 후 레이크 고유의 status 스트링은, main 후 레이 바의 status 의 값을 오버라이드 (override)합니다.

빌드 구성 필드 정의 및 사용

BuildConfigField

Gradle을 사용하면 buildConfigField 행에서 상수를 정의 할 수 있습니다. 이러한 상수는 런타임에 BuildConfig 클래스의 정적 필드로 액세스 할 수 있습니다. 이것은 defaultConfig 블록 내의 모든 필드를 정의한 다음 필요에 따라 개별 빌드 플래그로 재정의하여 을 생성하는 데 사용할 수 있습니다.

이 예제는 빌드 날짜를 정의하고 테스트보다는 프로덕션 빌드를 표시합니다.

android {
    ...
    defaultConfig {
        ...
        // defining the build date
        buildConfigField "long", "BUILD_DATE", System.currentTimeMillis() + "L"
        // define whether this build is a production build
        buildConfigField "boolean", "IS_PRODUCTION", "false"
        // note that to define a string you need to escape it
        buildConfigField "String", "API_KEY", "\"my_api_key\""
    }

    productFlavors {
        prod {
            // override the productive flag for the flavor "prod"
            buildConfigField "boolean", "IS_PRODUCTION", "true"
            resValue 'string', 'app_name', 'My App Name'
        }
        dev {
            // inherit default fields
            resValue 'string', 'app_name', 'My App Name - Dev'
        }
    }
}

자동 생성 된 <package_name>. gen 폴더의 BuildConfig .java에는 위의 지시문을 기반으로 다음 필드가 있습니다.

public class BuildConfig {
    // ... other generated fields ...
    public static final long BUILD_DATE = 1469504547000L;
    public static final boolean IS_PRODUCTION = false;
    public static final String API_KEY = "my_api_key";
}

정의 된 필드는 생성 된 BuildConfig 클래스에 액세스하여 런타임에 응용 프로그램 내에서 사용할 수 있습니다.

public void example() {
    // format the build date
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    String buildDate = dateFormat.format(new Date(BuildConfig.BUILD_DATE));
    Log.d("build date", buildDate);
    
    // do something depending whether this is a productive build
    if (BuildConfig.IS_PRODUCTION) {
        connectToProductionApiEndpoint();
    } else {
        connectToStagingApiEndpoint();
    }
}

ResValue

resValueproductFlavors 자원의 값을 생성한다. 모든 유형의 자원 ( string , dimen , color 등) 일 수 있습니다. 이는 적절한 파일에 자원을 정의하는 것과 유사합니다. 예를 들어 strings.xml 파일에서 string을 정의하는 것. 장점은 gradle에 정의 된 것이 productFlavor / buildVariant를 기반으로 수정할 수 있다는 것입니다. 값에 액세스하려면 자원 파일에서 res에 액세스하는 것과 동일한 코드를 작성하십시오.

getResources().getString(R.string.app_name)

중요한 점은이 방법으로 정의 된 리소스는 파일에 정의 된 기존 리소스를 수정할 수 없다는 것입니다. 새 자원 값만 작성할 수 있습니다.


Google Maps Android API와 같은 일부 라이브러리는 매니페스트에 meta-data 태그로 제공된 API 키가 필요합니다. 디버깅 및 프로덕션 빌드에 다른 키가 필요한 경우 Gradle로 채워진 매니페스트 자리 표시자를 지정하십시오.

AndroidManifest.xml 파일에서

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${MAPS_API_KEY}"/>

그런 다음 build.gradle 파일에 해당 필드를 설정하십시오.

android {
    defaultConfig {
        ...
        // Your development key
        manifestPlaceholders = [ MAPS_API_KEY: "AIza..." ]
    }

    productFlavors {
        prod {
            // Your production key
            manifestPlaceholders = [ MAPS_API_KEY: "AIza..." ]
        }
    }
}

Android 빌드 시스템은 여러 필드를 자동으로 생성하여 BuildConfig.java 배치합니다. 이 필드는 다음과 같습니다.

기술
DEBUG 앱이 디버그 또는 릴리스 모드인지 여부를 나타내는 Boolean
APPLICATION_ID 어플리케이션의 ID를 포함한 String (예 : com.example.app )
BUILD_TYPE 어플리케이션의 구축 형을 포함한 String (일반적으로, debug 또는 release )
FLAVOR 빌드의 특정의 후 레이 바를 포함한 String
VERSION_CODE 버젼 (빌드) 번호를 포함한 int
이것은 build.gradle versionCode 또는 AndroidManifest.xml versionCodebuild.gradle
VERSION_NAME 버젼 (빌드) 명을 포함한 String
이 같은입니다 versionNamebuild.gradle 또는 versionName 에서 AndroidManifest.xml

위와 더불어 여러 가지 크기의 flavor를 정의한 경우 각 차원마다 자체 값이 지정됩니다. 예를 들어 colorsize 대한 두 가지 크기의 풍미가있는 경우 다음 변수도 갖게됩니다.

기술
FLAVOR_color 「색」의 후 레이 바의 값을 포함한 String
FLAVOR_size 「사이즈」플레이버의 값을 포함한 String

"dependencies.gradle"파일을 통한 종속성 중앙 집중화

다중 모듈 프로젝트로 작업 할 때 의존성을 많은 빌드 파일, 특히 Android 지원 라이브러리 및 Firebase 라이브러리 와 같은 공용 라이브러리에 분산시키지 않고 단일 위치에 집중시키는 것이 유용합니다.

한 가지 권장 방법은 모듈 당 하나의 build.gradle 과 프로젝트 루트에 하나씩, 의존성에 대해 하나씩 Gradle 빌드 파일을 분리하는 것입니다. 예를 들면 다음과 같습니다.

root
  +- gradleScript/
  |     dependencies.gradle
  +- module1/
  |     build.gradle
  +- module2/
  |     build.gradle
  +- build.gradle

그런 다음 모든 종속성은 gradleScript/dependencies.gradle .

ext {
    // Version
    supportVersion = '24.1.0'

    // Support Libraries dependencies
    supportDependencies = [
            design:            "com.android.support:design:${supportVersion}",
            recyclerView:      "com.android.support:recyclerview-v7:${supportVersion}",
            cardView:          "com.android.support:cardview-v7:${supportVersion}",
            appCompat:         "com.android.support:appcompat-v7:${supportVersion}",
            supportAnnotation: "com.android.support:support-annotations:${supportVersion}",
    ]

    firebaseVersion = '9.2.0';

    firebaseDependencies = [
            core:         "com.google.firebase:firebase-core:${firebaseVersion}",
            database:     "com.google.firebase:firebase-database:${firebaseVersion}",
            storage:      "com.google.firebase:firebase-storage:${firebaseVersion}",
            crash:        "com.google.firebase:firebase-crash:${firebaseVersion}",
            auth:         "com.google.firebase:firebase-auth:${firebaseVersion}",
            messaging:    "com.google.firebase:firebase-messaging:${firebaseVersion}",
            remoteConfig: "com.google.firebase:firebase-config:${firebaseVersion}",
            invites:      "com.google.firebase:firebase-invites:${firebaseVersion}",
            adMod:        "com.google.firebase:firebase-ads:${firebaseVersion}",
            appIndexing:  "com.google.android.gms:play-services-appindexing:${firebaseVersion}",
    ];
}

그런 다음 최상위 수준의 파일 build.gradle 에서 해당 파일을 적용 할 수 있습니다.

// Load dependencies
apply from: 'gradleScript/dependencies.gradle'

그리고 module1/build.gradle 이렇게 :

// Module build file
dependencies {
    // ...
    compile supportDependencies.appCompat
    compile supportDependencies.design
    compile firebaseDependencies.crash
}

또 다른 접근법

버전 번호를 한 번 변수로 선언하고 모든 곳에서 사용하면 라이브러리 종속성 버전을 중앙 집중화하는 방법을 간략하게 파악할 수 있습니다.

작업 공간 루트 build.gradle 에 다음을 추가하십시오.

ext.v = [
    supportVersion:'24.1.1',
]

그리고 동일한 라이브러리를 사용하는 모든 모듈에서 필요한 라이브러리를 추가하십시오

compile "com.android.support:support-v4:${v.supportVersion}"
compile "com.android.support:recyclerview-v7:${v.supportVersion}"
compile "com.android.support:design:${v.supportVersion}"
compile "com.android.support:support-annotations:${v.supportVersion}"

풍미 특정 리소스를위한 디렉토리 구조

다양한 응용 프로그램 빌드에는 다양한 리소스가 포함될 수 있습니다. 풍미 특정 리소스를 만들려면 src 디렉토리에서 소문자로 된 풍미의 이름을 가진 디렉토리를 만들고 평소와 같은 방식으로 리소스를 추가하십시오.

예를 들어 풍미 Development 있고 고유 한 실행 프로그램 아이콘을 제공하려면 src/development/res/drawable-mdpi 디렉토리를 만들고 해당 디렉토리 내에 개발 관련 아이콘이있는 ic_launcher.png 파일을 만듭니다.

디렉토리 구조는 다음과 같습니다.

src/
  main/
    res/
      drawable-mdpi/
        ic_launcher.png  <-- the default launcher icon
  development/
    res/
      drawable-mdpi/
        ic_launcher.png  <-- the launcher icon used when the product flavor is 'Development'

물론이 경우 drawable-hdpi, drawable-xhdpi 등의 아이콘을 만들 수 있습니다.

Android Studio 프로젝트에 build.gradle 파일이 두 개있는 이유는 무엇입니까?

<PROJECT_ROOT>\app\build.gradle앱 모듈 에만 적용 됩니다 .

<PROJECT_ROOT>\build.gradle 은 모든 하위 프로젝트 / 모듈에 공통된 구성 옵션을 추가 할 수있는 "최상위 빌드 파일" 입니다.

프로젝트에서 다른 모듈을 로컬 라이브러리로 사용하는 경우 다른 build.gradle 파일이 있습니다. <PROJECT_ROOT>\module\build.gradle

최상위 레벨 파일에서 공통 특성을 buildscript 블록 또는 일부 공통 특성으로 지정할 수 있습니다.

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
       classpath 'com.android.tools.build:gradle:2.2.0'
       classpath 'com.google.gms:google-services:3.0.0'
    }
}

ext {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.1"
}

app\build.gradle 에서 모듈의 속성 만 정의합니다.

apply plugin: 'com.android.application'


android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
}

dependencies {
    //.....
}

gradle에서 쉘 스크립트 실행하기

쉘 스크립트는 빌드를 기본적으로 생각할 수있는 모든 것으로 확장하는 매우 다양한 방법입니다.

예제로 protobuf 파일을 컴파일하고 결과 java 파일을 추가 컴파일을 위해 소스 디렉토리에 추가하는 간단한 스크립트가 있습니다.

def compilePb() {
    exec {
        // NOTICE: gradle will fail if there's an error in the protoc file...
        executable "../pbScript.sh"
    }
}

project.afterEvaluate {
    compilePb()
}

이 예제의 'pbScript.sh'쉘 스크립트는 프로젝트의 루트 폴더에 있습니다.

#!/usr/bin/env bash
pp=/home/myself/my/proto

/usr/local/bin/protoc -I=$pp \
 --java_out=./src/main/java \
  --proto_path=$pp \
 $pp/my.proto \
 --proto_path=$pp \
 $pp/my_other.proto

Gradle 오류 디버깅

다음은 Gradle 에서 발췌 한 내용입니다. 0이 아닌 종료 값은 무엇이며 어떻게 수정합니까? , 전체 토론을 위해 그것을보십시오.

응용 프로그램을 개발 중이며 일반적으로 그렇게 보일 것 같은 약간의 Gradle 오류가 발생한다고 가정 해 봅시다.

:module:someTask FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':module:someTask'.
> some message here...  finished with non-zero exit value X
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: Y.ZZ secs

StackOverflow에서 문제를 검색하면 사람들이 프로젝트를 정리하고 다시 작성하거나 MultiDex를 사용 한다고 말하면서 시도하면 문제가 해결되지 않습니다.

더 많은 정보를 얻을 수있는 방법이 있지만, Gradle 출력 자체는 해당 메시지 위의 몇 줄에있는 실제 오류를 가리켜 야합니다. module:someTask FAILEDmodule:someTask FAILED :module:someOtherTask last :module:someOtherTask . 따라서 오류에 대한 질문을하는 경우 질문을 편집하여 오류에 대한 자세한 내용을 포함 시키십시오.

따라서 "0이 아닌 종료 값"을 얻습니다. 음, 그 숫자는 당신이 고쳐야하는 것을 나타내는 좋은 지표입니다. 다음은 가장 자주 발생하는 몇 가지 사례입니다.

  • 1 은 일반적인 오류 코드이며 오류는 Gradle 출력에있을 수 있습니다.
  • 2 는 겹치는 의존성 또는 프로젝트 구성 오류와 관련이있는 것으로 보입니다.
  • 3 너무 많은 의존성 또는 메모리 문제를 포함하는 것으로 보인다.

위의 일반적인 솔루션 (프로젝트의 Clean 및 Rebuild 시도 후)은 다음과 같습니다.

  • 1 - 언급 된 오류를 해결합니다. 일반적으로 이것은 컴파일 타임 오류입니다. 즉, 프로젝트의 일부 코드가 유효하지 않습니다. 여기에는 Android 프로젝트 용 XML과 Java가 모두 포함됩니다.
  • 2 & 3 - 여기에 나와있는 많은 답변을 통해 multidex 를 활성화 할 수 있습니다 . 문제를 해결할 수는 있지만 해결 방법 일 가능성이 큽니다. 당신이 왜 그것을 사용하고 있는지 이해하지 못한다면 (링크를보십시오), 아마 당신은 그것을 필요로하지 않을 것입니다. 일반적인 솔루션에는 라이브러리 의존성을 과도하게 줄이는 작업 (예 :지도 또는 로그인과 같은 하나의 라이브러리 만 사용해야하는 경우 모든 Google Play 서비스)이 포함됩니다.

빌드 유형 및 제품 특성에 대해 서로 다른 응용 프로그램 ID 지정

각 다른 응용 프로그램 ID 또는 패키지 이름을 지정할 수 있습니다 buildType 또는 productFlavor applicationIdSuffix 구성 속성을 사용하여 :

buildType 대한 applicationId 접미사의 예 :

defaultConfig {
    applicationId "com.package.android"
    minSdkVersion 17
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}

buildTypes {
    release {
        debuggable false      
    }

    development {
        debuggable true
        applicationIdSuffix ".dev"
    }

    testing {
        debuggable true
        applicationIdSuffix ".qa"
    }
}

결과로 얻은 applicationIds 는 다음과 같습니다.

  • 대한 com.package.android release
  • com.package.android. dev development 위한
  • com.package.android. testing 위한 qa

이것은 productFlavors 에서도 가능합니다.

productFlavors {
    free {
        applicationIdSuffix ".free"
    }
    paid {
        applicationIdSuffix ".paid"
    }
}

결과 applicationIds 는 다음과 같습니다.

  • com.package.android. 자유로운 풍미를 위해 free
  • com.package.android. 지불 paid

키 저장소 비밀번호를 노출하지 않고 APK에 서명하십시오.

다음 등록 정보를 사용하여 build.gradle 파일에서 apk에 서명하도록 서명 구성을 정의 할 수 있습니다.

  • storeFile : 키 스토어 파일
  • storePassword : 키 저장소 비밀번호
  • keyAlias : 키 별칭입니다.
  • keyPassword : 키 별칭 암호

대부분의 경우 build.gradle 파일에서 이러한 종류의 정보를 피할 필요가 있습니다.

방법 A : keystore.properties 파일을 사용하여 릴리스 서명 구성

keystore.properties 와 같은 속성 파일에서 서명 구성 정보를 읽을 수 있도록 앱의 build.gradle 을 구성 할 수 있습니다.

이와 같은 서명 설정은 다음과 같은 이유로 유용합니다.

  • 서명 구성 정보는 build.gradle 파일과 별개입니다.
  • 키 저장소 파일에 암호를 제공하기 위해 서명 프로세스 중에 개입 할 필요가 없습니다.
  • 버전 제어에서 keystore.properties 파일을 쉽게 제외 할 수 있습니다.

먼저 다음과 같이 내용이있는 프로젝트의 루트에 keystore.properties 라는 파일을 만듭니다 (이 값은 사용자 고유의 값으로 바꿉니다).

storeFile=keystore.jks
storePassword=storePassword
keyAlias=keyAlias
keyPassword=keyPassword

이제 앱의 build.gradle 파일에서 다음과 같이 signingConfigs 블록을 설정합니다.

android {
...

    signingConfigs {
        release {
            def propsFile = rootProject.file('keystore.properties')
            if (propsFile.exists()) {
                def props = new Properties()
                props.load(new FileInputStream(propsFile))
                storeFile = file(props['storeFile'])
                storePassword = props['storePassword']
                keyAlias = props['keyAlias']
                keyPassword = props['keyPassword']
            }
        }
    }
}

그게 전부 이지만 , 키 스토어 파일과 keystore.properties 파일을 버전 관리에서 제외하는 것을 잊지 마십시오 .

주목해야 할 몇 가지 :

  • keystore.properties 파일에 지정된 storeFile 경로는 앱의 build.gradle 파일에 상대적 build.gradle 합니다. 이 예제에서는 키 스토어 파일이 앱의 build.gradle 파일과 동일한 디렉토리에 있다고 가정합니다.
  • 이 예제에는 프로젝트 루트에 keystore.properties 파일이 있습니다. 다른 곳에 넣으면 rootProject.file('keystore.properties') 의 값을 프로젝트 루트와 관련하여 자신의 위치로 변경하십시오.

방법 B : 환경 변수 사용

속성 파일이 없어도 패스워드를 찾기가 더 어렵습니다.

android {

  signingConfigs {
    release {
        storeFile file('/your/keystore/location/key')
        keyAlias 'your_alias'
        String ps = System.getenv("ps")
        if (ps == null) {
             throw new GradleException('missing ps env variable')
        }
        keyPassword ps
        storePassword ps
    }
}

"ps" 환경 변수는 전역 변수 일 수 있지만 더 안전한 방법은 Android Studio의 셸에만 추가하는 것입니다.
리눅스에서이 작업은 Android Studio의 Desktop Entry 을 편집하여 수행 할 수 있습니다.

Exec=sh -c "export ps=myPassword123 ; /path/to/studio.sh"

자세한 내용은 이 항목을 참조하십시오.

"version.properties"파일을 통해 빌드 버전 관리

Gradle을 사용하여 빌드 할 때마다 패키지 버전을 자동 증가시킬 수 있습니다. 이렇게하려면 다음 내용으로 build.gradle 과 같은 디렉토리에 version.properties 파일을 작성하십시오.

VERSION_MAJOR=0
VERSION_MINOR=1
VERSION_BUILD=1

(메이저와 마이너의 값을 적절하게 변경). 그런 다음 build.gradle 에서 android 섹션에 다음 코드를 추가하십시오.

// Read version information from local file and increment as appropriate
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
  def Properties versionProps = new Properties()

  versionProps.load(new FileInputStream(versionPropsFile))

  def versionMajor = versionProps['VERSION_MAJOR'].toInteger()
  def versionMinor = versionProps['VERSION_MINOR'].toInteger()
  def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1

  // Update the build number in the local file
  versionProps['VERSION_BUILD'] = versionBuild.toString()
  versionProps.store(versionPropsFile.newWriter(), null)

  defaultConfig {
    versionCode versionBuild
    versionName "${versionMajor}.${versionMinor}." + String.format("%05d", versionBuild)
  }
}

이 정보는 완전한 {메이저}. {마이너}. {빌드} 번호에 대한 문자열 BuildConfig.VERSION_NAME 및 빌드 번호에 대한 정수형 BuildConfig.VERSION_CODE 로 Java에서 액세스 할 수 있습니다.

출력 apk 이름 변경 및 버전 이름 추가 :

이것은 출력 응용 프로그램 파일 이름 (.apk)을 변경하기위한 코드입니다. newName 다른 값을 할당하여 이름을 구성 할 수 있습니다.

android {

    applicationVariants.all { variant ->
        def newName = "ApkName";
        variant.outputs.each { output ->
            def apk = output.outputFile;

            newName += "-v" + defaultConfig.versionName;
            if (variant.buildType.name == "release") {
                newName += "-release.apk";
            } else {
                newName += ".apk";
            }
            if (!output.zipAlign) {
                newName = newName.replace(".apk", "-unaligned.apk");
            }

            output.outputFile = new File(apk.parentFile, newName);
            logger.info("INFO: Set outputFile to " 
                        + output.outputFile 
                        + " for [" + output.name + "]");
        }
    }
}

더 작은 APK 파일 크기에 대해 이미지 압축을 사용하지 않도록 설정

모든 이미지를 수동으로 최적화하는 경우 APK 파일러 크기를 줄이려면 APT Cruncher를 비활성화하십시오.

android {
    
    aaptOptions {
        cruncherEnabled = false
    }
}

gradle을 사용하여 Proguard 사용

응용 프로그램에 대한 Proguard 구성을 활성화하려면 모듈 수준의 gradle 파일에서 활성화해야합니다. minifyEnabled 의 값을 true 로 설정해야 true .

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

위의 코드는 모듈의 "proguard-rules.pro"파일과 함께 기본 Android SDK에 포함 된 Proguard 구성을 출시 된 apk에 적용합니다.

Gradle 및 AndroidStudio에 대한 실험용 NDK 플러그인 지원 사용

AndroidStudio의 NDK 지원을 향상시키기 위해 실험용 Gradle 플러그인을 사용 및 구성합니다. 다음 요구 사항을 충족하는지 확인하십시오.

  • Gradle 2.10 (이 예제의 경우)
  • Android NDK r10 이상
  • 빌드 도구 v19.0.0 이상이 포함 된 Android SDK

MyApp / build.gradle 파일 구성

예를 들어 build.gradle의 dependencies.classpath 행을 편집하십시오.

classpath 'com.android.tools.build:gradle:2.1.2'

classpath 'com.android.tools.build:gradle-experimental:0.7.2'

(v0.7.2는 작성 당시의 최신 버전 이었으므로 최신 버전을 직접 확인하고 그에 맞게 수정하십시오)

build.gradle 파일은 다음과 유사해야합니다.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.7.2'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

MyApp / app / build.gradle 파일 구성

다음 예제와 유사하게 build.gradle 파일을 편집하십시오. 귀하의 버전 번호가 다르게 보일 수 있습니다.

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion 19
        buildToolsVersion "24.0.1"

        defaultConfig {
            applicationId "com.example.mydomain.myapp"
            minSdkVersion.apiLevel 19
            targetSdkVersion.apiLevel 19
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-android.txt'))
            }
        }
        ndk {
            moduleName "myLib"
            
            /* The following lines are examples of a some optional flags that 
               you may set to configure your build environment
            */ 
            cppFlags.add("-I${file("path/to/my/includes/dir")}".toString())
            cppFlags.add("-std=c++11")
            ldLibs.addAll(['log', 'm'])
            stl = "c++_static"
            abiFilters.add("armeabi-v7a")
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

진행하기 전에 오류 메시지가 동기화되었는지 확인하고 동기화하십시오.

플러그인 사용 여부 테스트

먼저 Android NDK 모듈을 다운로드했는지 확인하십시오. 그런 다음 AndroidStudio에 새 앱을 만들고 ActivityMain 파일에 다음을 추가하십시오.

public class MainActivity implements Activity {
    onCreate() {
        // Pregenerated code. Not important here
    }
    static {
        System.loadLibrary("myLib");
    }
    public static native String getString();
}

getString() 부분은 해당 JNI 함수를 찾을 수 없다는 것을 나타내는 빨간색으로 강조 표시되어야합니다. 빨간색 전구가 나타날 때까지 마우스를 함수 호출 위로 가져갑니다. 전구를 클릭하고 create function JNI_... 선택하십시오. 이렇게하면 올바른 JNI 함수 호출로 myApp / app / src / main / jni 디렉토리에 myLib.c 파일이 생성됩니다. 다음과 유사해야합니다.

#include <jni.h>

JNIEXPORT jstring JNICALL 
Java_com_example_mydomain_myapp_MainActivity_getString(JNIEnv *env, jobject instance)     
{
    // TODO

    return (*env)->NewStringUTF(env, returnValue);
}

보이지 않는 경우 플러그인이 올바르게 구성되지 않았거나 NDK가 다운로드되지 않았습니다.

모든 gradle 프로젝트 작업 표시

gradlew tasks -- show all tasks

 

Android tasks
-------------
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for each variant.
sourceSets - Prints out all the source sets defined in this project.

Build tasks
-----------
assemble - Assembles all variants of all applications and secondary packages.
assembleAndroidTest - Assembles all the Test applications.
assembleDebug - Assembles all Debug builds.
assembleRelease - Assembles all Release builds.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
compileDebugAndroidTestSources
compileDebugSources
compileDebugUnitTestSources
compileReleaseSources
compileReleaseUnitTestSources
extractDebugAnnotations - Extracts Android annotations for the debug variant into the archive file
extractReleaseAnnotations - Extracts Android annotations for the release variant into the archive file
jar - Assembles a jar archive containing the main classes.
mockableAndroidJar - Creates a version of android.jar that's suitable for unit tests.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'LeitnerBoxPro'.
components - Displays the components produced by root project 'LeitnerBoxPro'. [incubating]
dependencies - Displays all dependencies declared in root project 'LeitnerBoxPro'.
dependencyInsight - Displays the insight into a specific dependency in root project 'LeitnerBoxPro'.
help - Displays a help message.
model - Displays the configuration model of root project 'LeitnerBoxPro'. [incubating]
projects - Displays the sub-projects of root project 'LeitnerBoxPro'.
properties - Displays the properties of root project 'LeitnerBoxPro'.
tasks - Displays the tasks runnable from root project 'LeitnerBoxPro' (some of the displayed tasks may belong to subprojects)
.

Install tasks
-------------
installDebug - Installs the Debug build.
installDebugAndroidTest - Installs the android (on device) tests for the Debug build.
uninstallAll - Uninstall all applications.
uninstallDebug - Uninstalls the Debug build.
uninstallDebugAndroidTest - Uninstalls the android (on device) tests for the Debug build.
uninstallRelease - Uninstalls the Release build.

Verification tasks
------------------
check - Runs all checks.
connectedAndroidTest - Installs and runs instrumentation tests for all flavors on connected devices.
connectedCheck - Runs all device checks on currently connected devices.
connectedDebugAndroidTest - Installs and runs the tests for debug on connected devices.
deviceAndroidTest - Installs and runs instrumentation tests using all Device Providers.
deviceCheck - Runs all device checks using Device Providers and Test Servers.
lint - Runs lint on all variants.
lintDebug - Runs lint on the Debug build.
lintRelease - Runs lint on the Release build.
test - Run unit tests for all variants.
testDebugUnitTest - Run unit tests for the debug build.
testReleaseUnitTest - Run unit tests for the release build.

Other tasks
-----------
assembleDefault
clean
jarDebugClasses
jarReleaseClasses
transformResourcesWithMergeJavaResForDebugUnitTest
transformResourcesWithMergeJavaResForReleaseUnitTest

"정렬되지 않은"apk 자동 삭제

자동으로 생성 된 apk 파일을 unaligned 접미사 (필요하지 않은 경우)가 필요하지 않은 경우 build.gradle 파일에 다음 코드를 추가 할 수 있습니다.

// delete unaligned files
android.applicationVariants.all { variant ->
  variant.assemble.doLast {
    variant.outputs.each { output ->
        println "aligned " + output.outputFile
        println "unaligned " + output.packageApplication.outputFile

        File unaligned = output.packageApplication.outputFile;
        File aligned = output.outputFile
        if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
            println "deleting " + unaligned.getName()
            unaligned.delete()
        }
    }
  }
}

여기에서

빌드 변형 무시

몇 가지 이유로 빌드 변형을 무시할 수 있습니다. 예를 들면 : 당신은 모의 제품 맛을 가지고 있으며, 단위 / 계측 테스트와 같은 디버깅 목적으로 만 사용합니다.

우리 프로젝트에서 mockRelease 변종을 무시합시다. build.gradle 파일을 열고 다음 을 작성합니다.

    // Remove mockRelease as it's not needed.
    android.variantFilter { variant ->
        if (variant.buildType.name.equals('release') && variant.getFlavors().get(0).name.equals('mock')) {
            variant.setIgnore(true);
        }
    }

의존성 트리보기

작업 종속성을 사용하십시오. 모듈 설정 방법에 따라 ./gradlew dependencies 이거나 모듈 응용 프로그램 사용의 종속성을 볼 수 있습니다 ./gradlew :app:dependencies

build.gradle 파일 다음 예제

dependencies {
    compile 'com.android.support:design:23.2.1'
    compile 'com.android.support:cardview-v7:23.1.1'

    compile 'com.google.android.gms:play-services:6.5.87'
}

다음 그래프가 생성됩니다.

Parallel execution is an incubating feature.
:app:dependencies

------------------------------------------------------------
Project :app
------------------------------------------------------------
. . .
_releaseApk - ## Internal use, do not manually configure ##
+--- com.android.support:design:23.2.1
|    +--- com.android.support:support-v4:23.2.1
|    |    \--- com.android.support:support-annotations:23.2.1
|    +--- com.android.support:appcompat-v7:23.2.1
|    |    +--- com.android.support:support-v4:23.2.1 (*)
|    |    +--- com.android.support:animated-vector-drawable:23.2.1
|    |    |    \--- com.android.support:support-vector-drawable:23.2.1
|    |    |         \--- com.android.support:support-v4:23.2.1 (*)
|    |    \--- com.android.support:support-vector-drawable:23.2.1 (*)
|    \--- com.android.support:recyclerview-v7:23.2.1
|         +--- com.android.support:support-v4:23.2.1 (*)
|         \--- com.android.support:support-annotations:23.2.1
+--- com.android.support:cardview-v7:23.1.1
\--- com.google.android.gms:play-services:6.5.87
     \--- com.android.support:support-v4:21.0.0 -> 23.2.1 (*)

. . .

여기에 프로젝트가 com.android.support:design 버전 23.2.1을 직접 포함하고 있음을 볼 수 있습니다. com.android.support:support-v4 는 버전 23.2.1입니다. 그러나 com.google.android.gms:play-services 자체는 동일한 support-v4 -v4에 종속되지만 이전 버전 인 21.0.0은 gradle에 의해 감지되는 충돌입니다.

(*) 는 이전에 이미 나열된 종속성 때문에 gradle이 하위 트리를 건너 뛸 때 사용됩니다.

중앙 버전 번호 / 빌드 구성에 gradle.properties 사용

중앙 구성 정보를 정의 할 수 있습니다.

또는 root gradle.properties 파일로 gradle.properties 하십시오.

프로젝트 구조

root
  +- module1/
  |     build.gradle
  +- module2/
  |     build.gradle
  +- build.gradle
  +- gradle.properties

gradle.properties의 모든 서브 모듈에 대한 전역 설정

# used for manifest
# todo increment for every release
appVersionCode=19
appVersionName=0.5.2.160726

# android tools settings
appCompileSdkVersion=23
appBuildToolsVersion=23.0.2

하위 모듈에서의 사용

apply plugin: 'com.android.application'
android {
    // appXXX are defined in gradle.properties
    compileSdkVersion = Integer.valueOf(appCompileSdkVersion)
    buildToolsVersion = appBuildToolsVersion

    defaultConfig {
        // appXXX are defined in gradle.properties
        versionCode = Long.valueOf(appVersionCode)
        versionName = appVersionName
    }
}

dependencies {
    ...
}

참고 : F-Droid 앱 스토어에 앱을 게시하려면 다른 f-droid 로봇이 현재 버전 번호를 읽지 않아서 버전 변경을 감지 / 확인할 수 없으므로 gradle 파일에서 매직 넘버를 사용해야합니다.

서명 정보 표시

일부 상황 (예 : Google API 키 얻기)에서 키 저장소 지문을 찾아야합니다. Gradle에는 키 저장소 지문을 포함한 모든 서명 정보를 표시하는 편리한 작업이 있습니다.

./gradlew signingReport

다음은 샘플 출력입니다.

:app:signingReport
Variant: release
Config: none
----------
Variant: debug
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: debugAndroidTest
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: debugUnitTest
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: releaseUnitTest
Config: none
----------

빌드 유형 정의

android {} 블록 내부의 모듈 수준 build.gradle 파일에서 빌드 유형 을 만들고 구성 수 있습니다.

    android {
        ...
        defaultConfig {...}
    
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
    
            debug {
                applicationIdSuffix ".debug"
            }
        }
    }


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow