How to create a release signed apk file using Grad

2018-12-31 20:56发布

I would like to have my Gradle build to create a release signed apk file using Gradle.

I'm not sure if the code is correct or if I'm missing a parameter when doing gradle build?

This is some of the code in my gradle file:

android {
    ...
    signingConfigs {
          release {
              storeFile file("release.keystore")
              storePassword "******"
              keyAlias "******"
              keyPassword "******"
         }
     }
}

The gradle build finishes SUCCESSFUL, and in my build/apk folder I only see the ...-release-unsigned.apk and ...-debug-unaligned.apk files.

Any suggestions on how to solve this?

26条回答
只靠听说
2楼-- · 2018-12-31 21:16

@Destil's answer is good if you can reuse the same configuration across all projects. Alternatively, Android Studio comes with a local.properties file that can maybe be used instead, but it's supposedly IDE-generated and I can't find a way to extend it from within Android Studio.

This is a variation of @jonbo's answer. That answer allows project specific settings but it comes with a bit of developer overhead. Specifically, significant boilerplate is required to move the signingConfigs definition into a separate file -- especially if you need to do so for multiple projects, which is a prime reason for picking this solution over Destil's. This can be somewhat alleviated by also including the line

apply plugin: 'com.android.application'

in the credentials file, as this will allow IDE completion.

Finally, most solutions here do not allow building the project in debug mode -- which handles debug-signing automatically -- without providing a syntactically if not semantically valid signingConfigs definition. If you do not need to produce a release build from a given machine, this extra step can be seen as an unnecessary obstacle. On the other hand, it can be an aid against ignorant or lazy colleagues running debug builds in production.

This solution will allow debug builds without worrying about credentials at all, but it will require valid credentials to produce release builds, and it takes very little boilerplate. However, as a downside it might encourage others to replace dummy values with real credentials and there's no way to protect against that.

// app/build.gradle
// Define this structure in signing.gradle to enable release builds.
ext.signing = [
        storeFilePath : 'path/to/keystore',
        storePassword : 'keystore password',
        keyAlias      : 'key alias',
        keyPassword   : 'key password',
]

if (file('signing.gradle').exists()) {
    apply from: 'signing.gradle'
}

android {
    ...
    signingConfigs {
        release {
            storeFile file(project.signing.storeFilePath)
            storePassword project.signing.storePassword
            keyAlias project.signing.keyAlias
            keyPassword project.signing.keyPassword
        }
    }
    buildTypes {
        debug { ... }
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

This creates a dummy property that serves purely to produce a syntactically valid build file. The values assigned to ext.signing's properties are irrelevant as far as debug builds go. To enable release builds, copy ext.signing into signing.gradle and replace the dummy values with valid credentials.

// signing.gradle
ext.signing = [
        storeFilePath : 'real/keystore',
        storePassword : 'real keystore password',
        keyAlias : 'real key alias',
        keyPassword : 'real key password',
]

Of course, signing.gradle should be ignored by VCS.

查看更多
梦醉为红颜
3楼-- · 2018-12-31 21:17

You can also use -P command line option of gradle to help the signing. In your build.gradle, add singingConfigs like this:

signingConfigs {
   release {
       storeFile file("path/to/your/keystore")
       storePassword RELEASE_STORE_PASSWORD
       keyAlias "your.key.alias"
       keyPassword RELEASE_KEY_PASSWORD
   }
}

Then call gradle build like this:

gradle -PRELEASE_KEYSTORE_PASSWORD=******* -PRELEASE_KEY_PASSWORD=****** build

You can use -P to set storeFile and keyAlias if you prefer.

This is basically Destil's solution but with the command line options.

For more details on gradle properties, check the gradle user guide.

查看更多
墨雨无痕
4楼-- · 2018-12-31 21:19

In newer Android Studio, there is a GUI way which is very easy and it populates Gradle file as well.

  1. File -> Project Structure

  2. Module -> Choose the main module ('app' or other custom name)

  3. Signing tab -> Plus image to add new configuration

  4. Fill data on the right side

  5. OK and Gradle file is automatically created

  6. You will manually have to add a line signingConfig signingConfigs.NameOfYourConfig inside builtTypes{release{}}

Images:

enter image description here

enter image description here

Two important(!) notes:

(EDIT 12/15)

  1. To create signed APK, you'd have to open Terminal tab of Android Studio (the bottom of the main interface) and issue a command ./gradlew assembleRelease

  2. If you forgot keyAlias (what happens often to me), you will have to initiate Build -> Generate Signed APK to start the process and see the name of the Alias key.

查看更多
余生无你
5楼-- · 2018-12-31 21:21

To complement the other answers, you can also place your gradle.properties file in your own module folder, together with build.gradle, just in case your keystore is specific to one project.

查看更多
冷夜・残月
6楼-- · 2018-12-31 21:22

If you have the keystore file already, it can be as simple as adding a few parameters to your build command:

./gradlew assembleRelease \
 -Pandroid.injected.signing.store.file=$KEYFILE \
 -Pandroid.injected.signing.store.password=$STORE_PASSWORD \
 -Pandroid.injected.signing.key.alias=$KEY_ALIAS \
 -Pandroid.injected.signing.key.password=$KEY_PASSWORD

No permanent changes to your Android project necessary.

Source: http://www.tinmith.net/wayne/blog/2014/08/gradle-sign-command-line.htm

查看更多
深知你不懂我心
7楼-- · 2018-12-31 21:22

I had quite a lot of fun figuring this one out. Here is my walk-through.

A to Z walk-through on how to create a gradle build file in IntelliJ (v.13.1.4) This walk-through assumes you know how to make a keystore file. For this tutorial to work you will need your keystore file to be located in your app folder and you will need to have your zipalign.exe file to be located in 'SDK-ROOT\tools'. This file is usually found in 'SDK-ROOT\build-tools' and under this folder it will be in the highest api folder (alpha or beta I recommend the alpha version).

For those of you that wish to jump straight in here is the gradle build file.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
}
android {
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    signingConfigs {
        playstore {
            keyAlias 'developers4u'
            keyPassword 'thisIsNotMyRealPassword'
            storeFile file('developers4u.keystore')
            storePassword 'realyItIsNot'
        }
    }
    buildTypes {
        assembleRelease {
            debuggable false
            jniDebugBuild false
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            zipAlign true
            signingConfig signingConfigs.playstore
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:20.0.0'
    compile 'com.android.support:appcompat-v7:20.0.0'
}

You can build part of this build file (above) from menu option: File/Project Structure From here select Facets and click 'Android-Gradle(App). From here you will see tabs: 'Properties', 'Signing', 'Flavors', 'Build Types' and 'Dependencies' for this walk-through we will just be using 'Signing' and 'Build Types'. Under 'Build Types' (in the name section) enter any name that you wish to identify your build type configuration and in the other 4 fields enter your keystore information (setting the keystore path the the one under your app folder).

Under the 'Build Types' enter the value 'assembleRelease' into the name field, 'Debuggable' should be set to false, 'Jni Debug Build' should be false, set 'Run Proguard' to true and 'Zip Align' to true. This will generate build file, but not as depicted above, you will have to add a few things to the build file afterwards. The ProGuard file location here will be set manually in the gradle build file. (as depicted above)

The DSL containers you will have to add afterwards are as follows:

android {
    ....
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ....
}

You will also have to add:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:20.0.0'
    compile 'com.android.support:appcompat-v7:20.0.0'
}

note this DSL container above('dependencies') should be at the bottom of the config file but not inside the android DSL container. In order to build the dependencies container from the IntelliJ menu, select: File/Project Structure. From there select Facets again and then Android-Gradle(app). You will see the same 5 tabs as mentioned above. Select the 'Dependencies' tab and add the dependencies you require.

After all of this is done you should see a Gradle build file similar to the file at the top of this walk-through. To build your signed zip aligned release you will need to open the Gradle tasks. You can get to this window by selecting View/Tool Windows/Gradle. From here you can double Click 'assembleAssembleRelease. This should generate your deployable APK.

The potential problems that can occur when compiling your release are (but not limited to): Your Gradle build file being in the wrong place. There are two Gradle build files; one in your application root folder and another in the app folder under the application root. You must user the latter.

You may also have lint problems. (Note: Android Developer Studio is much better at spotting Lint problems than IntelliJ you will notice this when trying to generate an signed APK from the menu options)

To get around lint problems you will need to put the following DSL container inside the android container (at the top):

android {
        ....
    lintOptions {
        abortOnError false
    }
    ....
}

putting this inside your android DSL container will cause an error file to be generated in the build folder (directly under your app folder) the file name should be something like 'lint-results-release-fatal.html' this file will tell you the the class where the error occurred. Another file that will be generated is an XML file that contains the 'issue ID' associated with the lint error. The file name should be something like 'lint-results-release-fatal.xml'. Somewhere near the top of the file you will see a node 'issue' inside which you will see something similar to 'id="IDOfYourLintProblem"'

To correct this problem open the file in your project that was listed in the 'lint-results-assembleRelease-fatal.html' file and enter the following line of code in the Java Class file just above the class name: @SuppressLint("IDOfYourLintProblem"). You may have to import 'android.annotation.SuppressLint;'

So your java class file should appear like:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

import android.annotation.SuppressLint;
... other imports

@SuppressLint("IDOfYourLintProblem")
public class SearchForJobsFragment extends Fragment {... rest of your class definition}

Note that suppressing lint errors is not always the best IDEA you may be better off to change your code that caused the lint errors.

Another problem that could potentially occur is if you have not set the environment variable for the Gradle HOME environment variable. This variable is named 'GRADLE_HOME' and should be set the the path of the gradle home directory, something like 'C:\gradle-1.12' Sometimes you may also want to set the environment variable for 'ANDROID_HOME' set this to 'YOUR-SDK-Root\sdk'

After this is done return to the Gradle tasks window and double click the assembleAssembleRelease.

If all is successful you should be able to go to the folder app\build\apk and find your deployable APK file.

查看更多
登录 后发表回答