详解android项目配置签名文件的完整流程

Posted xiaopangcame

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解android项目配置签名文件的完整流程相关的知识,希望对你有一定的参考价值。

1.背景

接手的项目近期需要上线,于是复习了一下项目签名文件配置流程,这里做个系统性总结。

2.最终目标

根据需求为debug包与release包配置签名文件,快速满足中小型项目的需要。

3.创建签名文件

要将签名文件配置到项目中,首先需要创建一个签名文件。android studio为我们提供了图形化创建方式,这里简单赘述一下:

导航栏build下选择 generate signed bundle/apk,如下图:

国内的就选择apk,点击next:

点击 create new,创建一个新的签名文件:

接下来需要填入一些信息,下面的截图简单解释了一下。其中,certificate下的六个填空题,做一个就可以了,这里建议应填尽填:

填完之后,点击OK,进行创建,完事儿~ 等等?咋还报错了嘞?瞅瞅说的啥。。。

哦~ 他让咱们用命令行迁移到行业标准格式,那来吧:复制一下警告弹窗里的那条命令(keytool -importkeystore......pkcs12),打开terminal终端,粘贴进去,点回车,走你~ 按照提示,输入源秘钥库口令,就是刚刚设置的密码,再回车,走你~ OK,到这里,签名文件就创建完成了。

4.生成release与debug签名文件的配置信息

我们需要在app的build.gradle下生成测试包与正式包的配置脚本,来分别配置debug包与release包的不同属性,比如测试包与正式包都使用自己的签名文件、正式包开混淆但测试包不开等等,方便我们进行开发与上线。 android studio也为我们提供了图形化操作界面,下面一起来走一遍:

导航栏 file -> project structure,进到项目结构界面

项目结构界面依次选择: modules -> app -> signing configs,如下图:

点击“+”新增一个配置信息,输入release,代表这是用于正式包的签名文件信息,点击OK:

输入相关信息后,点击 apply,release包的签名文件就生成完毕了,同理,生成debug包的签名文件配置信息,用于日常开发与调试,这里建议与release包使用相同的签名文件,避免相同包名的debug版本与release版本,由于签名不同而重复卸载与安装(插个题外话:必须要让debug包与release包使用不同签名文件的小伙伴,可以采用给测试包追加包名的方式,避免正式包与测试包的包名冲突,这里先挖个坑【坑1】,下文来填上)。 release签名文件配置如图:

debug签名文件配置如图:

点击OK之后,等待项目配置完成,然后打开项目app目录下的build.gradle文件,我们可以看到,release包的签名信息与debug包的签名信息都已经生成,如图:

但是目前为止,我们仅仅是生成了自己的两种签名文件信息,却还没配置到测试包与正式包里。那么怎么在编译测试包或者正式包的时候,让他们各自使用自己的签名文件信息呢?先别捉急,咱喝口茶缓一缓先。

5.将签名文件信息配置给对应的包

喝着茶咱也别闲着,来看一看app目录下build.gradle里面的buildType的信息:

这个bulidType里,记录着项目的release包、debug包等各种包的配置。咱们可以看到,创建项目的时候,系统为咱们显式自动生成了release包的配置,但是只配置了两个值,这里简单解释一下:

  • minifyEnabled:是否开启混淆(debug模式默认为true,release模式默认false)
  • proguardFiles:混淆文件(仅在minifyEnabled为true时生效) OK,接下来咱们先配置release包的签名文件,依旧是打开项目结构界面,但是选择 build variants,如图:

咱们看到,系统已经生成了一个release,这个就是正式包的配置文件,咱们这次只需要设置一下签名文件就OK了,别的设置可以自行了解。在signing config下选择设置的signingConfigs.release选项,点击apply来应用设置。 编译完成后,回到app目录下的build.gradle,查看buildTypes,如图:

到这里,release包的签名文件便配置完成了。 接下来配置debug包的签名文件,依旧是打开项目结构界面创建变量界面(file-> project structure -> build variants ),选择app包:

点击“+”号,输入debug,点击OK后,debug包的各项默认配置便显示出来了。

咱们可以根据需要来更改这些配置,比如,Debuggable(应用是否可调试,底下解释【埋坑2】)默认值是true,这时候咱们可以显式的指定出来,就给它默认值改为手动设置的true,当然,这里不改也是没问题的。Debuggable如下图:

【坑2】解释:debuggable,顾名思义,就是是否可调式,指的是应用在运行过程中,能否通过编译器进行调试,最直接的表现就是系统日志输出。默认情况下,release包下处于关闭模式,debug包处于开启模式,开发过程中,必要情况下可以更改该值来调试debug包或者release包。

配置debug包签名文件操作与配置release包的签名文件基本一样,找到 signing config,选择签名文件,然后点击apply来应用配置,最后OK,如下图:

同步完成后,可以看到编译器已经为我们自动产生了debug包的配置信息,并应用了咱们自定义的签名文件:

到这里,签名文件的基本配置流程已经讲完了,但是这样的配置是会产生签名文件信息的安全问题的。 在谈安全问题之前,咱们先填一填前面埋的【坑1】:关于在debug包追加包名的事儿。有兴趣的小伙伴来了解一下,没兴趣的可以跳下一小节了。 前面提到,为了避免测试包与正式包安装冲突,咱们可以使用两种方式,一种是上面的使用同一个签名文件,另一种是给测试包追加包名,让他们包名不同,从而避免包名冲突。android studio同样为我们提供了图形化追加包名的方式,甚至刚刚我们还见到过。

[ 黑人问号脸.jpg ]

不信你看截图:

没错,就是在这里追加包名,比如我的demo的默认包名是com.dylan.signaturetest,我想让测试包的包名是com.dylan.signaturetest.debug,那么我只需要在这个application id suffix里添加“.debug”即可,如图:

依次点击apply与OK后,等待同步完成,查看build.gradle的配置如下:

可以看到,applicationIdSuffix属性已经被添加成功,这时候我们分别运行正式包与测试包,运行方式如图:

运行结果如图:

可以看到,两个包可以同时存在,查看包名,如图:

正如我们期望的那样,正式包与测试包同时存在了。 OK,上面埋的坑填完了,底下讲一讲上文提到的,签名文件信息安全问题。

6.将签名文件信息移动到项目本地配置文件

前面我们发现,签名文件的文件名、密码等极其敏感的信息,都是放在项目app包下的build.gradle里的,会随着项目的发包,一起发到各大应用市场,这样安装包被不怀好意的玩家们进行反编译后,轻而易举的就可以获取到我们的签名文件信息。除此之外,文件路径写在gradle里,在多端协作开发同一个项目的时候,大家的签名文件放置的位置五花八门,也会引起这里gradle文件的签名文件路径被多人频繁修改的问题。 为了避免这种情况,往往我们会将签名文件的配置信息单独在本地配置文件local.properties里,该文件在新建项目的时候,android studio会帮我们创建好,位于项目根目录下,在进行Git版本控制时,默认不会被添加到Git提交到远程仓库,在别人第一次拉取远程仓库代码时,只需要创建自己的local.properties文件即可。文件截图如下:

可以看到,我们的android SDK路径就是在这里配置的,底下我们来编写代码,来实现从local.properties文件里读取签名文件信息。

首先,local.properties文件内指定签名文件路径、密码、别名、别名密码等信息,如图:

接着在app目录下的build.gradle文件的android下编写代码,读取local.properties文件,并读取指定的信息,如图:

最后,将读取到的签名文件信息配置给signingConfigs内debug与release,如图:

至此,签名文件从产生到配置的完整流程,算是已经讲完了。

7.总结

本文讲解了从零开始配置一个android项目签名文件的完整流程,通过阅读本文,我们可以对签名文件配置有一个整体的把握,后续配置签名文件也可以一文搞定。 由于笔者能力有限,文章难免出现错误,欢迎指正!

附录:相关源码

核心配置文件一共两点,即项目根目录下的local.properties与app目录下的build.gradle文件的android属性,分别如下:

local.properties

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=C\\:\\\\Users\\\\Dylan\\\\AppData\\\\Local\\\\Android\\\\Sdk
#
#签名文件配置信息
keyStoreFile=C\\:\\\\Users\\\\Dylan\\\\Desktop\\\\signatureTest.jks
keyStorePassword=123456
keyAlias=key0
keyAliasPassword=123456

复制代码

使用的时候更换为自己的签名文件相关信息。

app//build.gradle

android {

    // 读取local.properties文件
    Properties properties = new Properties()
    InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream()
    properties.load(inputStream)

    // 读取签名文件
    def keyKeyStoreFile = file(properties.getProperty('keyStoreFile'))
    // 读取签名文件别名、密码等信息
    def keyKeyStorePassword = properties.getProperty('keyStorePassword')
    def keyKeyAlias = properties.getProperty('keyAlias')
    def keyKeyAliasPassword = properties.getProperty('keyAliasPassword')


    signingConfigs {
        release {
            storeFile keyKeyStoreFile
            storePassword keyKeyStorePassword
            keyAlias keyKeyAlias
            keyPassword keyKeyAliasPassword
        }
        debug {
            storeFile keyKeyStoreFile
            storePassword keyKeyStorePassword
            keyAlias keyKeyAlias
            keyPassword keyKeyAliasPassword
        }
    }
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.dylan.signaturetest"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
            debuggable true
            applicationIdSuffix '.debug'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}
复制代码

以上是关于详解android项目配置签名文件的完整流程的主要内容,如果未能解决你的问题,请参考以下文章

Android打包流程

APK签名机制之——V2签名机制详解

xcode 5:代码签名身份列表不完整

iOS应用发布流程详解

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | dvmDexFileOpenPartial | dexFileParse | 脱壳点 | 获取 dex 文件在内存中的首地址 )(代码片

Android 安装包优化使用 lib7zr.so 动态库处理压缩文件 ( jni 中 main 函数声明 | 命令行处理 | jni 调用 lib7zr.so 函数库处理压缩文件完整代码 )(代码片