Android studio之签名配置

转自:http://blog.csdn.net/caben_/article/details/52708169

我们可以新建一个项目,然后生成一个新的签名文件。 
一般来说,经过这些操作之后,我们便可以通过点击左上角的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

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

这里写图片描述

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

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

至此,我们的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

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

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

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

keystore.path=../test.jks              //替换成自己的签名路径
keystore.password=123456        
keystore.alias=test
keystore.alias_password=123456
   
   
  • 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.properties
def keyfile = file('s.keystore.temp')

Properties properties = new Properties()
// local.properties file in the root director
properties.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

首先,便是给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

相应的,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

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

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

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

    lintOptions {
        abortOnError false
    }
   
   
  • 1
  • 2
  • 3

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

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

或者指定JDK的编译版本

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
   
   
  • 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

最后,附上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.properties
def keyfile = file('s.keystore.temp')

Properties properties = new Properties()
// local.properties file in the root director
properties.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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值