文章目录
- 1 build.gradle配置
- 1.1 project下的build.gradle
- 1.2 module下的build.gradle
- 2 Apk版本号的命名规则及配置方法
- 2.1 命名规则
- 2.2 配置方法
- 2.3 生成apk命名
- 3 Android studio 3.0以下及3.0以上gradle dependencies依赖的区别
- 4 Dependencies依赖关键字的区别
本文章为公司练习markdown使用的文章,此处只用来记录,不公开文章。
1 build.gradle配置
Gradle是Android Studio开发工具自带的一个依赖插件,也可以进行项目、lib和本地jar包的依赖,它是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置,语法上更为简单。
Android Studio下有两种build.gradle文件,一种为project下的,另一种为module下的,顾名思义前者是定义于适用于整个工程的配置文件,后者则是模块下的配置文件。
1.1 project下的build.gradle
这个是Android Studio 3.1自动生成的build.gradle。
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
1.buildscript:配置存储库和Gradle本身的依赖,一般此处无需我们修改。
repositories:配置Gradle的存储库,一般有jcenter(),maven();
dependencies:配置了Gradle需要使用的依赖;
classpath:buildscript所需的插件和依赖;
2.allprojects:配置存储库和项目中所有模块(如第三方插件)使用的依赖项或库;
3.task:执行的工作单元,此处是项目clean的时候删除buildDir文件夹;
1.2 module下的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.excellence.test"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.jakewharton:butterknife:5.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
1.apply:标明此module的类型。
apply plugin: ‘com.android.application’ // app应用程序
apply plugin: ‘com.android.library’, // 库
apply from:‘config.gradle’ //用于给本地文件系统提供路径或到远程位置的URL的脚本插件
例:项目XXX下有app、common两个模块。
1.1 在app模块下打包则app下的build.gradle头部应为:
apply plugin: ‘com.android.application’
1.2 common作为依赖的库,其下的build.gradle的头部应为:
apply plugin: ‘com.android.library’
2.android:android的配置;
3.compileSdkVersion:编译应用使用的sdk版本;
4.apllicationId:包名;
5.minSdkVersion:支持的最小SDK版本,即在小于此版本的系统上不可使用;
6.targertSdkVersion:目标版本;应用已兼容从minSdkVersion至tartgetSdkVersion之间所有api的变化;
7.versionCode:版本号;只能为整型;
8.versionName:版本名;字符串类型;
9.testInstrumentationRunner:测试框架;
10.buildType:指定生成安装文件的相关配置;
11.release:发布版本配置;
12.minifyEnabled:混淆设置ture为加混淆,false为不加;使用混淆是为了软件的安全,在反编译下不易被读。
13.proguardFiles:混淆的规则文件;表示混淆文件在app目录下的位置。
14.dependencies:依赖的包、模块等;项目需要使用的库、包都要在此处进行关联;
15.implementation:远程依赖的库;
16.testImplementation:测试依赖的库;
17.androidTestImplementation:测试用例库;
其他:
signingConfigs:
signingConfigs { //签名配置
release { //发布版
try {
storeFile file(".\\platform.keystore") //签名文件在app目录下的位置,使用绝对路径也可,如:E:\1.jks
storePassword "android" //签名证书的密码
keyAlias "user" //签名文件中的别名
keyPassword "pwd" //签名文件中的密码
v1SigningEnabled true //仅验证未解压的文件内容
v2SigningEnabled true //验证压缩文件的所有字节
} catch (ex) {
}
}
debug { //测试版
try {
storeFile file(".\\platform.keystore")
storePassword "pwd"
keyAlias "user"
keyPassword "pwd"
v1SigningEnabled true
v2SigningEnabled true
} catch (ex) {
}
}
}
关于apk打包时 v1 和 v2 的勾选,v2 不勾选会在Android7.0以上出问题,原因是在 Android 7.0 以上版本的设备上,APK 可以根据Full Apk Signature(v2方案)或者JAR-signed(v1方案)进行验证;而对于7.0以下版本的设备其会忽略 v2 版本的签名,只验证 v1 签名,所以必须 v1 和 v2都进行勾选。
包名和签名文件是用来区分软件是否为同一应用的。如果出现冲突会导致软件装不上。
签名文件可以自己创建也可以选择已有的签名文件。打包的时候需要输入密码等参数,如下图所示:
productFlavors:
productFlavors { // 发布的应用市场,第三节对于此有详细说明
yunyongbao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yunyongbao"]
}
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
}
dependencies:
implementation project(':upgradelib') //依赖module ‘upgradelib’
implementation files('libs/retrofit.jar') //依赖jar包
2 Apk版本号的命名规则及配置方法
为了确定测试版本和发布版本,为了后续的研发、维护和扩展,对Apk版本进行规范的命名是十分必要的。
app下的build.gradle中含有versionCode和versionName两个参数可以用来表示app的版本号。versionCode是仅供内部使用的版本号,为整型,一般使用默认的就行。versionName则是可供用户可见的版本名称。
2.1 命名规则
- <主版本号>.<子版本号>.<阶段版本号>_ <日期号>_<SVN号>
如:V1.0.2_20180816_16575
主版本号:当功能模块有较大的变动,比如增加多个模块或者整体架构发生变化。
子版本号:一定的功能变化等。
阶段版本号:如修复有了一些bug或者一些小的变动等。
日期号:编译成apk的日期。
SVN号:编译apk时的当前SVN版本号。
2.2 配置方法
主版本、子版本号以及阶段版本号由项目决定是否修改。日期号以及SVN号则通过代码进行获取。获取SVN版本号,需要关联SVN。
(1)在工程下的build.gradle下添加如下代码,关联SVN的库:
classpath group: 'org.tmatesoft.svnkit', name: 'svnkit', version: '1.8.11'
(2)在app下build.gradle里面添加如下代码,获取SVN版本号,日期信息等:
import org.tmatesoft.svn.core.wc.ISVNOptions
import org.tmatesoft.svn.core.wc.SVNClientManager
import org.tmatesoft.svn.core.wc.SVNRevision
import org.tmatesoft.svn.core.wc.SVNStatus
import org.tmatesoft.svn.core.wc.SVNStatusClient
import org.tmatesoft.svn.core.wc.SVNWCUtil
// 打包时间
def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
// 获得SVN版本号
def getSvnRevision() {
ISVNOptions options = SVNWCUtil.createDefaultOptions(true); //获取SVN配置的一个对象
SVNClientManager clientManager = SVNClientManager.newInstance(options); //svn client 管理
SVNStatusClient statusClient = clientManager.getStatusClient(); // 状态信息
SVNStatus status = statusClient.doStatus(projectDir, false); // 获得状态信息的一个副本
SVNRevision revision = status.getCommittedRevision() // 当前SVN版本
return revision.getNumber()
}
(3)修改:
versionName "V0.0.1_" + releaseTime() + "_" + getSvnRevision()
(4)在代码中获取versionName:
String versionName = null;
PackageManager pm = context.getPackageManager(); // 应用程序基本信息管理
PackageInfo pi = null;
try {
pi = pm.getPackageInfo(context.getPackageName(), 0); //程序信息
versionName = pi.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
2.3 生成apk命名
由于安卓是在不同的应用市场发布的,这时候我们可以利用多渠道多版本工具productFlavors进行打包,并对不同渠道的apk进行不同包名的命名以区分。
(1)在build.gradle文件的android{}下加入需要发布的版本,如:
productFlavors {
demo1 {
}
demo2 {
}
}
可以在demo1设置中对文件属性进行替换,如:
// 替换manifest文件中name为UMENG_CHANNEL_VALUE的value为abc
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "abc"]
// 对生成程序的包名替换
applicationId "com.xxx.xxx"
(2)配置apk文件名:
android studio 3.0以下:
applicationVariants.all { variant -> // 变体
variant.outputs.each { output ->
// 生成名字为 name.apk 的安装包
output.outputFile = new File(output.outputFile.parent,"name.apk" );
}
}
android studio 3.0以上:
applicationVariants.all { variant ->
variant.outputs.all { output ->
// 文件名 此处获取的是productFlavors的名称
outputFileName = "${variant.productFlavors[0].name}" + ".apk"
// 打包时Flavors选demo1,则生成文件名为demo1.apk的安装包
// 打包时Flavors选demo2,则生成文件名为demo2.apk的安装包
}
}
如下图所示:
3 Android studio 3.0以下及3.0以上gradle dependencies依赖的区别
dependencies的主要用途为:
- 声明对模块的依赖关系
- 声明一个文件的依赖
- 声明一个项目依赖关系
- 从模块依赖关系中解析特定工件
- Gradle特定依赖关系
Android Studio 3.0以下gradle的使用dependencies的方式一般为compile,
3.0以上新增了关键字implementation和api,而compile提示已过时。
关键字api与compile功能一致,但3.0以上却提倡使用Implementation,因为Implementation对于使用了该命令编译的依赖,对该项目有依赖的项目将无法访问到使用该命令编译的依赖中的任何程序,也就是将该依赖隐藏在内部,而不对外部公开。
通俗来讲就是假设A使用的是implementation依赖某库,B工程依赖了A,但B无法使用某库的方法,就是implementation依赖。反之,如果A使用的是compile或者api依赖的某库,B依赖了A,那么B也相当于依赖了这个库。
Implementation隐藏了不必要对外的接口,对于大型项目来说还加快了编译的速度。假设模块B依赖了模块A,模块C依赖了模块B,这个时候修改了模块A的代码,如果是使用的是compile(API)依赖,因为C也能访问到A的接口,那么A、B、C都需要编译,但如果使用的是Implementation,C访问不到A的接口,那么可以只对A和B进行编译,加快了编译的速度。
4 Dependencies依赖关键字的区别
Android3.0以下及以上除去新增关键字Implementation,基本无太大区别。
3.0以下 | 3.0以上 | 用法 |
无 | implementation | 参与编译,会打包,但依赖不具有传递性 |
compile | API | 参与编译,会打包到debug/release apk中 |
Provided | Compile only | 只参与编译,不会打包到debug/release apk中 |
APK | Runtime only | 不参与编译,只会打包到debug/release apk中 |
Test compile | Test implementation | 只参与单元测试编译,不会打包到debug/release apk包中 |
Debug compile | Debug implementation | 只参与debug编译,只会打包到debug apk中 |
Release compile | Release implementation | 只参与Release编译,只会打包到Release apk中 |