Android Gradle 配置小窥

文章目录

文档 Android Plugin DSL Referencel

一 从build.gradle文件中分离签名信息

如果你是开源项目,建议这么做。否则最好不要暴露签名信息。以下仅供参考。

1. 在项目根目录下创建文件 keystore.properties

storePassword="myStorePassword"
keyPassword="mykeyPassword"
keyAlias="myKeyAlias"
storeFile="myStoreFileLocation"

2. 在 build.gradle 文件中如下配置

...

// 创建一个 keystorePropertiesFile 变量,在 rootProject 文件夹下初始化
// keystore.properties 文件.
def keystorePropertiesFile = rootProject.file("keystore.properties")

// 初始化一个新的 Properties() 对象.
def keystoreProperties = new Properties()

// 在 keystoreProperties 对象中加载 keystore.properties 文件keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {
     signingConfigs {
        config {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
        }
    }
}

这样就把签名信息分离出来了,方便了替换。

附:命令行签名

1. 使用命令行生成私钥

$ keytool -genkey -v -keystore my-release-key.keystore
-alias alias_name -keyalg RSA -keysize 2048 -validity 10000

这个命令会提示你输入 keystore 和 key 的密码, 以及一些列信息。-validity 指的是有效期天数。最后会生成 my-release-key.keystore 文件。

2. 编译获取一个 unsigned APK

3. 使用 jarsigner 签名 app

$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1
-keystore my-release-key.keystore my_application.apk alias_name

这个命令会提示你输入 keystore 和 key 的密码.

4. 验证签名

$ jarsigner -verify -verbose -certs my_application.apk

也可以通过解压 apk,获取 META-INF 文件夹下的 CERT.RSA 信息进行验证:

keytool -printcert -file CERT.RSA

5. 优化

$ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

二 build.gradle 标签 android{}

android 标签下的配置与生成的 BaseExtension.class 里的方法相对应,。

public abstract class BaseExtension implements AndroidConfig{}

AndroidConfig 接口里声明 android 标签的配置,源码如下,所有的属性配置及含义点击查看:BaseExtension .

1. defaultConfig { } && productFlavors { }

配置 App 的产品特性, defaultConfig 是默认的产品特性,自定义的 productFlavors 里的所有特性都各自继承 defaultConfig 的特性。
更有趣的是~~

(1).可以给生成的 BuildConfig 类添加新字段:buildConfigField(type, name, value)

(2).添加一个新资源(resValue(类型, 名字, value)):resValue("string", "apiurl", "http://blog.csdn.net/yang786654260"),build之后就可以通过 R.string.apiurl 获取,其他类型也一样。

(3).给清单文件中添加可变变量(manifestPlaceholders ),例如:

manifestPlaceholders = [googlekey: "xxxxxxxxxxxx", facebook_app_id: "1111111111",
                                    app_name: "APPPP"]

把配置的 key-value 存在了 map 对象(mManifestPlaceholders)中,build之后在清单文件中动态获取值如下:

	android:label="${app_name}"
	<meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${googlekey}" />
	<meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="${facebook_app_id}" />

建议 把 Key 放到 build.gradle里。

(4).multiDexEnabled, https://developer.android.com/studio/build/multidex.html,超过 64K 方法的解决办法如下:
build.gradle:

android {
    defaultConfig {
        // Enabling multidex support.
        multiDexEnabled true
    }
}

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}

Application:

public void onCreate(Bundle arguments) {
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);
    ...
}

(5)设置 productFlavors 后,运行 app,就可以在Build Variant 选择相应的版本进行编译。
Build Variant

2. aaptOptions { }

Android Asset Packaging Tool, 是用来打包 APK 是工具。aaptOptions { } 是对打包工具的配置。

3. adbOptions { }

timeOutInMs 用于配置 adb 命令的超时。
installOptions 用于对安装命令的配置,例如:installOptions “-d", "-t"

4. buildTypes { }

配置编译类型,可以给 applicationId 加后缀(applicationIdSuffix),配置app名字,配置签名,添加版本号后缀(versionNameSuffix),zipalign ,去除无用资源(shrinkResources),配置混淆文件等。
更有趣的是~~(同 上 )
1.可以给生成的 BuildConfig 类添加新字段:buildConfigField(type, name, value)
2.添加一个新资源(resValue(类型, 名字, value)):resValue("string", "apiurl", "http://blog.csdn.net/yang786654260"),build之后就可以通过 R.string.apiurl 获取,其他类型也一样。
3.给清单文件中添加可变变量(manifestPlaceholders ),例如:

manifestPlaceholders = [googlekey: "xxxxxxxxxxxx", facebook_app_id: "1111111111",
                                    app_name: "APPPP"]

把配置的 key-value 存在了 map 对象(mManifestPlaceholders)中,build之后在清单文件中动态获取值如下:

	android:label="${app_name}"
	<meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${googlekey}" />
	<meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="${facebook_app_id}" />

建议 把 Key 放到 build.gradle里。

5. compileOptions { }

用于指定 Java 源码和编译的 版本,以及源码的编码格式。

6. dataBinding { }

databinding 的配置。databinding 详解。

7. dexOptions { }

在这里可以配置:

  • javaMaxHeapSize(例:“2048m”);
  • jumboMode(是否开启jumbo 模式);
  • dexInProcess(是否运行 dx 编译器时作为一个独立的进程或内部JVM Gradle守护进程。这样可以极大的提高性能,但是还在实验阶段);
  • maxProcessCount(dex最大并发进程,默认是4,并发进程的内存需求:Total Memory = getMaxProcessCount() * getJavaMaxHeapSize(), 故这两个的配置要适当以避免 trashing);
  • preDexLibraries(这可以提高增量构建,但clean构建可能会慢一些。)
  • threadCount(dx 运行时使用的线程数,默认是4)

8. jacoco { }

Java Code Coverage, http://www.eclemma.org/jacoco/。

9. lintOptions { }

强大的 lint 的配置。

10. packagingOptions { }

有个错误:Error: duplicate files during packaging of APK,就是在这里解决的:

packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/notice.txt'
    }

11. signingConfigs { }

签名文件的配置。

12. sourceSets { }

配置各种资源源码路径。例如(下面示例解决了 .so 文件不在 jniLibs 文件夹下就无法识别的Error):

sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

13. splits { }

http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits

14. testOptions { }

注:以上部分配置可以使用 Android Studio 的图形界面,但又局限性。

三 APK 打包自动更换路径以及文件名

Gradle 3.3及以上 使用

 release {
            signingConfig signingConfigs.release
            debuggable false
            zipAlignEnabled true
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationVariants.all { variant ->
                if (variant.buildType.name == "release"){
                    variant.getPackageApplicationProvider().get().outputDirectory = new File("${rootProject.ext.outputDirectory}")
                    variant.getPackageApplicationProvider().get().outputScope.apkDatas.forEach { apkData ->
                        if (apkData != null && apkData.outputFileName.endsWith('release.apk')){
                            def fileName =
                                    "${getApkPrefixName()}_${variant.productFlavors[0].name}_${defaultConfig.versionCode}_v${defaultConfig.versionName}_${releaseTime()}.apk"
                            apkData.outputFileName = fileName
                        }
                    }
                }
            }
        }
static def releaseTime() {
    return new Date().format("yyyyMMdd.kkmm", TimeZone.getTimeZone("GMT+8"))
}

static def getApkPrefixName() {
    return "YourApkName"
}

apk打包路径配置

static def isMac() {
    return System.properties['os.name'].toLowerCase().contains('mac')
}
static def isWindows() {
    return System.properties['os.name'].toLowerCase().contains('windows')
}

static def getSystemUserName(){
    return System.properties['user.name']
}

static def getApkSavedPath() {
    if (isMac()) {
        return "/Users/${getSystemUserName()}/Desktop/release"
    }
    return "C:/Users/${getSystemUserName()}/Desktop/release"
}

ext {

    outputDirectory = getApkSavedPath()
  }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值