android之Gradle常见使用

这一篇主要是说下gradle的一些常见使用,主要是几点配置:

目录

配置库工程的路径

定义gradle额外变量

配置签名文件

配置apk输出文件名:

配置清单文件(AndroiodMenifest)占位符

配置不同包名

配置全局变量

在字符串的xml文件中添加新值

配置生成jar包(包含新版(studio 4.1.1)如何生成jar)

jar包混淆(Android studio)

全局解决依赖冲突


  • 配置库工程的路径

include ':app', ':netlib',':emptylib'
settings.project(':emptylib').projectDir = file('empty/library')

在settings.gradle这样配置后,是什么意思呢?可以理解为就是将empty/library下的库工程取名为emptylib,在这样配置并build后,再来看下工程的目录结构有什么变化:

  • 定义gradle额外变量

对于一个工程来说,可能会包含多个project,每个project可能会有一些相同的配置,这时就可以将这些相同的配置额外的提取出来 ,这里下来看个简单的例子:

先在settings.gradle中如下配置:

include ':app', ':netlib'
gradle.ext.custom = 'custom'

然后在build.gradle中添加如下输出代码:

apply plugin: 'com.android.application'
println gradle.ext.custom

输出结果就是上面配置custom,这个配置还可以在延伸一下,新建一个config.gradle文件,这个名字可以随便取,只要是以.gradle结尾就可以了,接下来就可以在这个文件中配置一下全局变量了:

ext {
    android = [
            compileSdkVersion    :   27,
            minSdkVersion        :   19,
            targetSdkVersion     :   27,
            versionCode          :   1,
            versionName          :   "1.0"
    ]

    version = [
            androidSupportSdkVersion      :   "27.1.1",
            retrofitSdkVersion            :   "2.4.0"
    ]

    dependencies = [
            //surport
            "appcompat-v7"                :   "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}",
            "design"                      :   "com.android.support:design:${version["androidSupportSdkVersion"]}",
            "support-v4"                  :   "com.android.support:support-v4:${version["androidSupportSdkVersion"]}",
            "cardview-v7"                 :   "com.android.support:cardview-v7:${version["androidSupportSdkVersion"]}",
            "annotations"                 :   "com.android.support:support-annotations:${version["androidSupportSdkVersion"]}",
            "recyclerview-v7"             :   "com.android.support:recyclerview-v7:${version["androidSupportSdkVersion"]}",

    ]
}

这样配置完后,但还没有引入到gradle中,那要怎么引入呢?很简单,只需要rootProject的build.gradle中在添加一行代码就ok:

apply from: 'config.gradle'

这样配置完后,就可以在其他的build.gradle中去引用了,比如:

android {
    compileSdkVersion rootProject.ext.android['compileSdkVersion']
    defaultConfig {
        applicationId "com.example.zzq.urlrequest"
        minSdkVersion rootProject.ext.android['minSdkVersion']
        targetSdkVersion rootProject.ext.android['targetSdkVersion']
        versionCode rootProject.ext.android['versionCode']
        versionName rootProject.ext.android['versionName']
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

这样配置的好处是,当有多个project时,由于某些原因需要更改一些设置时,那就不用每个都去改了,直接在配置(config.gradle)文件中修改下就ok了。当然还有另一种方式,使用起来也更简单,接下来就来唠唠:

在工程文件下有个gradle.properties文件,这个文件有什么用呢?就是给.gradle文件添加属性,也就是说只要在gradle.properties中添加的属性,在.gradle文件中是可以直接使用,那就来看看怎么用了:

1、先在gradle.properties文件中做如下配置:

minSdkVersionPro        =   19
targetSdkVersionPro     =   27
versionCodePro          =   1
versionNamePro          =   1.0

2、接下就是在.gradle文件中去使用了:

android {

    println minSdkVersionPro
    println targetSdkVersionPro
    println versionCodePro
    println versionNamePro
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.zzq.urlrequest"
        minSdkVersion minSdkVersionPro
        targetSdkVersion targetSdkVersionPro
        versionCode versionCodePro.toInteger()
        versionName versionNamePro
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

}

看下输出:

19
27
1
1.0

对于有些属性定义在gradle.properties中是会包异常的,比如定义compileSdkVersion这个属性,使用的时候就会包异常,至于什么原因,暂时还不知道。所以这个用起来会比较简单,但是可能有一些坑要填。

再来说最后一种定义.gradle文件的属性,不过这种定义方式只是在当前文件中有效,但是没什么坑:

def compileSdkVersionPro = 27
android {
    ...
    compileSdkVersion compileSdkVersionPro
    ...
}

如果定义的属性只是当前文件有效,优先采用这种方式。

  • 配置签名文件

要配置签名文件首先得有签名文件,这个这里就不多说了,有了签名文件后就可以在app模块下的build.gradle文件下进行配置,这里采用的是图形界面作说明,那这个图形界面在哪呢?看下图:

或者使用快捷键:ctrl+alt+shift+s (这里使用的是android studio默认的快捷键)

出现的界面如下:

这样配置好后,点击确定就完成配置了,其实际上是在app模块下的build.gralde文件里生成代码,来看看生成的代码:

android {
    signingConfigs {
        config {
            keyAlias 'alias'
            keyPassword '123456'
            storeFile file('NetRequest.jks')
            storePassword '123456'
        }
    }
}

如果你比较熟悉了,直接手写这段代码就可以了,至此签名文件配置就算完成了,这里应该还有一个疑惑,就是file(‘NetRequest.jks’)这个是什么意思,这里其实就是指向NetRequest.jks这个文件,只不过我这里使用的想对路径,当然你也可以使用绝对路径,这里在贴下我放置这个文件的位置:

好了,签名文件就说到这里了。

  • 配置apk输出文件名:

android studio 3.0之前和之后配置是不一样的,而且是兼容的,这里针对是3.0之后的版本:

android {
    applicationVariants.all { variant ->
        variant.outputs.all {
            println "outputFile = "+outputFile
            println "outputFileName = "+outputFileName
            outputFileName = "${variant.name}_${getTime()}_${variant.versionName}"
            println "modify outputFileName = "+outputFileName
        }
    }
}
def getTime(){
    new Date().format('yyyMMdd',TimeZone.getTimeZone('UTC'))
}

这里打印了两个东西,来看下输出:

outputFile = E:\AndroidWorkProject\NetRequest\app\build\outputs\apk\debug\app-debug.apk
outputFileName = app-debug.apk
modify outputFileName = debug_20180926_1.0
outputFile = E:\AndroidWorkProject\NetRequest\app\build\outputs\apk\release\app-release.apk
outputFileName = app-release.apk
modify outputFileName = release_20180926_1.0

这里有个需要注意的地方,这里只能配置outputFileName这个属性,不能配置outputFile,配置了这个会报异常,如下:

Cannot set the value of read-only property 'outputFile',意思就是说这个属性是一个只读属性,getTime()获取的是当前时间。

  • 配置清单文件(AndroiodMenifest)占位符

比如在在清单文件有如下配置:

<meta-data android:name="zzq"
            android:value="${zzq_name}"/>

可以看到这里value还没有赋值,这时就可以在build.gradle中进行动态配置,这样的配置在多版本中配置的比较多。

看下在app模块下build.gradle中是如何配置:

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            manifestPlaceholders = [zzq_name : 'tangedegushi_release']
        }
        debug {
            manifestPlaceholders = [zzq_name : 'tangedegushi_debug']
        }
    }

配置完成了,接下来就是来查看效果了,查看效果有两种方式,

1、是在代码中去获取值然后打印出来;

2、同步工程后在合并的清单文件中查看;

代码方式(这里以Application节点为例):

ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
String zzq = appInfo.metaData.getString("zzq");

清单文件中查看,首先得知道合并后的清单文件在哪,如下图:

上面红框中的清单文件就是合并后的清单文件,下面这个就是编译的版本(我是这么理解的,也可以说是变体),这里可以选择对应的版本,这里配置的只有两个,一是debug,二是release,选择其中一个,那么合并后的清单文件中就会产生对应的值。比如这里选的是debug版本,那么效果如下:

        <meta-data
            android:name="zzq"
            android:value="tangedegushi_debug" />
  • 配置不同包名

有时可能会遇到这样的问题,开发调试时一般安装的debug版本,但有时又需要安装release版本,这时可能会出现安装不了的情况,这问题就是由包名相同引起的,为了预防这样的问题,就可以在debug和release版本下配置不同的包名,如下:

        debug {
            applicationIdSuffix '.debug'
        }

这样配置后就会在原包名后面添加.debug这个后缀,而release下面不配置,默认使用的就是原包名。

  • 配置全局变量

比如在应用开发的时候有网络请求,开发时的url和正式发布时的url可能就不一样,这时就可以在这里配置了。

        release {
            buildConfigField('boolean','isDebug','false')
            buildConfigField('String','baseUrl','\"http://www.wanandroid.com/\"')
        
        }

        debug {
            buildConfigField('boolean','isDebug','true')
            buildConfigField('String','baseUrl','\"http://www.wanandroid.com/test/\"')
        }

url根据实际情况配置,这样配置好后,同步下工程,就会生成一个BuildConfig的java类,这个类里面全是静态的,看下这个文件的所在位置,如下图:

  • 在字符串的xml文件中添加新值

比如:

        debug {
            resValue('string','my_name','android')
        }

接下来就可以在代码中使用了:

String appName = getResources().getString(R.string.my_name);

这里需要注意,如果这里只是在debug版本中添加了,那么只有在编译debug版本中才能用,编译的其他版本是没有这个属性的。上面讲的这些属性同样需要注意这点,不过在正常开发中,一般不会再在一个版本中配置,通常都是所有版本中都会配置。

  • 配置生成jar包(包含新版(studio 4.1.1)如何生成jar)

这里我把他分为两步,一是配置自己jar的一些参数,二是配置生成jar的任务,这里就直接上代码了

1、配置参数,如果闲麻烦,可以直接在配置任务的地方去生成:

ext {
    JAR_VERSION = rootProject.ext.versions.versionName
    JAR_NAME = "cruzr-device-control"
    JAR_OUTPUT_DIR = 'build/libs'
    JAR_ORIGINAL_PATH = 'build/intermediates/packaged-classes/release/classes.jar'
}

2、配置生成任务:

task makeJar(type: Jar) {
    from zipTree(file(JAR_ORIGINAL_PATH))
    // 添加assets文件夹,如果不需要请删除该行
    //from fileTree(dir: 'src/main', includes: ['assets/**'])
    baseName "${JAR_NAME}_${JAR_VERSION}_${releaseTime()}"
    destinationDir file(JAR_OUTPUT_DIR)
}

def static releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}

这样配置完成后,最后就只剩在控制台输入命令:gradlew makeJar(这里是方法的名字),这样就over了。

这里就先说到这,有什么不懂的欢迎一起讨论,下一篇再来说下版本差异化打包如何配置!

在新版的gradle中对这块有改动,以我目前studio 4.1.1的版本为例

task makejar(type:Jar,dependsOn: [':concurrent:assembleRelease',....]){
    baseName("asyncTask")
    archiveVersion = "1.0"

    exclude('**/R.class')
    exclude('**/R$*.class')
    exclude('**/BuildConfig.class')
    exclude('**/BuildConfig$*.class')
    exclude('android/')
    
    from("../模块名/build/intermediates/javac/release/classes")
    from 'build/intermediates/javac/debug/classes'
}

dependsOn:这个可有可没有,建议加上,如果不加上,每次在执行生产jar包命令时,都需要先build下,否则可能会有一些后面加的内容没有打进jar包或jar包中没有内容

baseName:生产jar包的名称,和archiveName有点像,不同的是archiveName需要加.jar的后缀,archiveName已经被废除,不推荐使用

archiveVersion:生成jar包的版本号

exclude:移除不需要的类

from:定义哪些类需要打进jar包中,如果没有定义,生成的jar包会没有内容

如果需要将资源文件打包进jar包,需要加上:

    from fileTree(dir: 'src/main', includes: ['assets/**'])
    from fileTree(dir: 'src/main', includes: ['res/**'])

如果需要jar包打进jar包:

    from(project.zipTree('libs/adapter.jar'))

  • jar包混淆(Android studio)

jar包的混淆是基于已经生成jar的情况下,上面有说到jar包的生成,这里就继续接着往下说说混淆:

task proguardJar(type: proguard.gradle.ProGuardTask, dependsOn: "build") {
    //混淆配置
    configuration 'proguard-rules.pro'
    // 未混淆的jar路径
    injars 'build/libs/source.jar'
    // 混淆后的jar输出路径
    outjars 'build/libs/proguard.jar'
}

任务创建后,接着就是执行任务gradlew proguardJar

如果想让第二个任务基于第一个执行,可以添加

proguardJar.dependsOn(makejar)

这样,直接执行第二个任务的时候会先去执行第一个任务,也就是先执行makejar->proguardJar

关于混淆配置,可以先将一些常用配置添加进去,对于有其他jar包依赖的,需要加

-libraryjars 'C:\Users\Administrator\AppData\Local\Android\Sdk\platforms\android-29\android.jar'
-libraryjars '../speech/libs/adapter.jar' //后面这个是jar包路径

如果没有对依赖的jar包指定路径,执行任务时会报错

  • 全局解决依赖冲突

在模块目录的build.gradle如下配置:

configurations {
// 移除指定模块
//    implementation.exclude group:'com.android.support',module:'appcompat-v7'
    all {
        resolutionStrategy {
// 强制使用指定版本
//        force 'com.android.support:appcompat-v7:25.2.0'
//        force "com.github.bumptech.glide:glide:4.9.0"
            eachDependency {
                DependencyResolveDetails details ->
                    println "app group = ${details.requested.group}"
//                    if (details.requested.group == 'com.github.bumptech.glide' && details.requested.name == 'glide') {
//                        details.useVersion '3.6.0'
//                    }
            }
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值