详解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 逆向整体加固脱壳 ( DEX 优化流程分析 | dvmDexFileOpenPartial | dexFileParse | 脱壳点 | 获取 dex 文件在内存中的首地址 )(代码片
Android 安装包优化使用 lib7zr.so 动态库处理压缩文件 ( jni 中 main 函数声明 | 命令行处理 | jni 调用 lib7zr.so 函数库处理压缩文件完整代码 )(代码片