Android studio签名配置

来源:互联网 发布:excel单元格重复数据 编辑:程序博客网 时间:2024/05/17 06:07

在上一篇教程中,我讲解了Android studio多渠道打包的相关配置,在这一篇博客中,我们将继续讲解android studio的签名配置。如果还没有看过上一篇的朋友,或者还不了解多渠道打包的,可以先看这一篇博客

http://blog.csdn.net/caben_/article/details/52682462

Let’s Go,让我们开始新的教程。
我们可以新建一个项目,然后生成一个新的签名文件。
一般来说,经过这些操作之后,我们便可以通过点击左上角的Build->Generate Signed APK->Next,然后选择对应的Build Type进行打包。

那对一些人来说,这样也太麻烦了,每次都得输入相关信息,还得进行选择,这怎么能忍!
那么有更简单快捷的方法吗?答案是有的。

我们可以在项目的app目录下的build.gradle中进行签名的配置。
首先我们找到build.gradle下的android{},默认配置如下所示

这里写图片描述

接下来呢,我们可以把项目的预览模式调成Project,不调也行,只需把刚才生成的签名文件放至到对应的目录下即可。我的做法是直接放至到项目下,如图所示

这里写图片描述

然后,回到app下的build.gradle,在里面增加这段代码

signingConfigs {        debug {            storeFile file('../test.jks')//签名文件路径            storePassword "123456"            keyAlias "test"            keyPassword "123456"  //签名密码            println("====== signingConfigs.debug ======")        }        release {            storeFile file('../test.jks')//签名文件路径            storePassword "123456"            keyAlias "test"            keyPassword "123456"  //签名密码            println("====== signingConfigs.release ======")        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我来解释一下,storeFile file对应的就是签名文件key的路径,我们的签名放在项目的直接子路径下,而build.gradle在test/app下,所以我们要用 .. 找到项目的根路径,再通过 / 找到对应的签名文件所在路径。当然,你也可以自己配置签名文件的地址,只要能找到即可。

这里写图片描述

此时,我们在项目路径下的app/build/outputs可以看到我们打包的apk,从名字可以看出,该APK是已经签名的。那么就是说,用代码配置,可以达到和使用图形界面一样的效果。

对了,这里有一点需要注意,就是signingConfigs代码块一定要写在buildTypes前面,否则会报下面这种错: Could not find property ‘debugConfig’ on SigningConfigContainer.

至此,我们的buildTypes的配置可以这样:

buildTypes {        debug {            println("====== buildTypes.debug ======")            signingConfig signingConfigs.debug        }        release {            //是否混淆            minifyEnabled false            //是否移除无用资源            zipAlignEnabled true            println("====== buildTypes.release ======")            signingConfig signingConfigs.release            //混淆的配置文件            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

大家现在便可以通过命令行进行任意操纵,或者进行多渠道打包。
不过,上述的配置虽然配置简单,但是存在不安全性,假如你的项目是开源的,你把签名文件的配置密码之类的信息用明文写在build.gradle里面,那是不是很不安全呢?

所以,我们可以这么做。在项目路径下新建一个.properties的文件,或者直接local.properties下直接添加相关信息即可。

我们可以直接在该文件下添加:(填写相关信息)

keystore.path=../test.jks              //替换成自己的签名路径keystore.password=123456        keystore.alias=testkeystore.alias_password=123456
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

那么,在build.gradle下面,为了不用明文显示,我们首先要获得key的相关配置,所以我们可以在app的build.gradle下面新增该代码

def keystoreFilepath = ''def keystorePSW = ''def keystoreAlias = ''def keystoreAliasPSW = ''// default keystore file, PLZ config file path in local.propertiesdef keyfile = file('s.keystore.temp')Properties properties = new Properties()// local.properties file in the root directorproperties.load(project.rootProject.file('local.properties').newDataInputStream())keystoreFilepath = properties.getProperty("keystore.path")if (keystoreFilepath) {    keystorePSW = properties.getProperty("keystore.password")    keystoreAlias = properties.getProperty("keystore.alias")    keystoreAliasPSW = properties.getProperty("keystore.alias_password")    keyfile = file(keystoreFilepath)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

首先,便是给key赋默认值,然后根据Properties的配置文件,然后根据我们在local.properties下的配置参数keystore.password等获取签名文件的配置信息。

这里有一点需要强调,在Git版本控制的项目中,我们可以看到我们项目下有一个.gitignore的文件,里面的配置大概如下所示

这里写图片描述

我们可以看到/local.properties,意思就是说local.properties默认是不添加到版本控制里面的,因为local.properties存储的是我们环境资源的一些相关信息,如sdk的路径。故我们可以在local.properties下配置签名信息而不用担心密钥外泄。对于开源项目来说,是非常好的。

那么,此时此刻,我们app/build.gradle下的signingConfigs可以改为:

signingConfigs {        debug {            storeFile keyfile            storePassword keystorePSW            keyAlias keystoreAlias            keyPassword keystoreAliasPSW            println("====== signingConfigs.debug ======")        }        myConfig {            storeFile keyfile            storePassword keystorePSW            keyAlias keystoreAlias            keyPassword keystoreAliasPSW            println("====== signingConfigs.release ======")        } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

相应的,buildTypes也可以配置成这样

buildTypes {        debug {            println("====== buildTypes.debug ======")            signingConfig signingConfigs.debug        }        release {            //是否混淆            minifyEnabled false            //是否移除无用资源            zipAlignEnabled true            //混淆配置            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            //签名文件存在,则签名            if (keyfile.exists()) {                println("WITH -> buildTypes -> release: using jks key")                signingConfig signingConfigs.myConfig            }else {                println("WITH -> buildTypes -> release: using default key")            }            applicationVariants.all { variant ->                variant.outputs.each { output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {                        // 输出apk名称为ruijie_v1.0_wandoujia.apk                        def fileName = "ruijie_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"                        output.outputFile = new File(outputFile.parent, fileName)                    }                }            }        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这样的话,当我们的项目是开源的,那么我们不会上传签名文件,我们通过上述代码keyfile.exists()进行判断是否有签名,那么其他人打包出来的apk是未签名的。所以能够保证apk签名的安全性。

附加一下:build.gradle的相关配置:

有时候我们打包会显示lint报错,那么我们可以添加

    lintOptions {        abortOnError false    }
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

dx工具(android将jar包转成dex格式二进制jar包工具)
这将应用所有使用dex的task。解决65535的配置

dexOptions {        incremental true        javaMaxHeapSize "4g"        //关闭预编译        preDexLibraries = false    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

或者指定JDK的编译版本

compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

打包忽略掉第三方jar相同的文件

 packagingOptions {        exclude 'META-INF/DEPENDENCIES.txt'        exclude 'META-INF/LICENSE.txt'        exclude 'META-INF/NOTICE.txt'        exclude 'META-INF/NOTICE'        exclude 'META-INF/LICENSE'        exclude 'META-INF/DEPENDENCIES'        exclude 'META-INF/notice.txt'        exclude 'META-INF/license.txt'        exclude 'META-INF/dependencies.txt'        exclude 'META-INF/LGPL2.1'    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

最后,附上build.gradle部分配置的相关代码:

apply plugin: 'com.android.application'apply plugin: 'me.tatarka.retrolambda'apply plugin: 'android-apt'def keystoreFilepath = ''def keystorePSW = ''def keystoreAlias = ''def keystoreAliasPSW = ''// default keystore file, PLZ config file path in local.propertiesdef keyfile = file('s.keystore.temp')Properties properties = new Properties()// local.properties file in the root directorproperties.load(project.rootProject.file('local.properties').newDataInputStream())keystoreFilepath = properties.getProperty("keystore.path")if (keystoreFilepath) {    keystorePSW = properties.getProperty("keystore.password")    keystoreAlias = properties.getProperty("keystore.alias")    keystoreAliasPSW = properties.getProperty("keystore.alias_password")    keyfile = file(keystoreFilepath)}android {    compileSdkVersion 24    buildToolsVersion "24.0.2"    defaultConfig {        applicationId "com.example.vizax.with"        minSdkVersion 15        targetSdkVersion 24        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        multiDexEnabled true    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    // 这个是解决lint报错的代码    lintOptions {        abortOnError false    }    dexOptions {        incremental true        javaMaxHeapSize "4g"        //关闭预编译        preDexLibraries = false    }    /*android {        productFlavors {            kuan {                manifestPlaceholders = [UMENG_CHANNEL_VALUE: "kuan"]            }            xiaomi {                manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]            }            qh360 {                manifestPlaceholders = [UMENG_CHANNEL_VALUE: "qh360"]            }            baidu {                manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]            }            wandoujia {                manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]            }        }    }*/    android {        productFlavors {            kuan {}            xiaomi {}            qh360 {}            baidu {}            wandoujia {}            yingyongbao {}        }        productFlavors.all {            flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]        }    }    signingConfigs {        debug {            storeFile keyfile            storePassword keystorePSW            keyAlias keystoreAlias            keyPassword keystoreAliasPSW            println("====== signingConfigs.debug ======")        }        myConfig {            storeFile keyfile            storePassword keystorePSW            keyAlias keystoreAlias            keyPassword keystoreAliasPSW            println("====== signingConfigs.release ======")        }        /*release {            storeFile file('../with.jks') //签名文件路径            storePassword "with123456"            keyAlias "with"            keyPassword "with123456"  //签名密码        }*/    }    //打包忽略掉第三方jar相同的文件    packagingOptions {        exclude 'META-INF/DEPENDENCIES.txt'        exclude 'META-INF/LICENSE.txt'        exclude 'META-INF/NOTICE.txt'        exclude 'META-INF/NOTICE'        exclude 'META-INF/LICENSE'        exclude 'META-INF/DEPENDENCIES'        exclude 'META-INF/notice.txt'        exclude 'META-INF/license.txt'        exclude 'META-INF/dependencies.txt'        exclude 'META-INF/LGPL2.1'    }    /*signingConfigs代码块一定要写在buildTypes前面,否则会报下面这种错:    Could not find property 'debugConfig' on SigningConfig container.    签名密码写在gradle中不安全,故最好在打包上线的时候将相关代码注释掉。*/    buildTypes {        debug {            println("====== buildTypes.debug ======")            signingConfig signingConfigs.debug        }        release {            //是否混淆            minifyEnabled false            zipAlignEnabled true            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            if (keyfile.exists()) {                println("WITH -> buildTypes -> release: using jks key")                signingConfig signingConfigs.myConfig            }else {                println("WITH -> buildTypes -> release: using default key")            }            applicationVariants.all { variant ->                variant.outputs.each { output ->                    def outputFile = output.outputFile                    if (outputFile != null && outputFile.name.endsWith('.apk')) {                        // 输出apk名称为ruijie_v1.0_wandoujia.apk                        def fileName = "ruijie_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"                        output.outputFile = new File(outputFile.parent, fileName)                    }                }            }        }    }    /*  左下角打开Terminal,输入命令行        如果我们想打包wandoujia渠道的release版本,执行如下命令就好了:        gradlew assembleWandoujiaRelease        如果我们想打包wandoujia渠道的debug版本,执行如下命令就好了:        gradlew assembleWandoujiaDebug        如果我们只打wandoujia渠道版本,则:        gradlew assembleWandoujia        此命令会生成wandoujia渠道的Release和Debug版本        同理我想打全部Release版本:        gradlew assembleRelease*/}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164

至于混淆的相关配置,稍后我在下一篇博客进行详细讲解。
如果有任何疑问,欢迎留言。谢谢。