Android Gradle 构建

常用配置

“gradle.properties”

加快gradle构建速度:

# 并行构建
org.gradle.parallel=true
# 开启Gradle守护进程
org.gradle.daemon=true
# 配置JVM
org.gradle.jvmargs=-Xms1024m -Xmx1024m

“/app/build.gradle”

// 声明是Android程序。可以理解为该 model 为一个 com.android.application 程序,也就是应用程序
apply plugin: 'com.android.application'
// 把当前module设置为android library库
// apply plugin: 'com.android.library'

android {
    // 编译SDK的版本
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    defaultConfig {
        // 应用的包名
        applicationId rootProject.ext.applicationId
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        multiDexEnabled true // 解决65K方法限制
        ndk {
            // abiFilters "x86", "armeabi-v7a", "armeabi"
            abiFilters "armeabi-v7a"
        }

        // 手动导入Eclipse-Android项目,需要配置以下一些Dirs
        sourceSets {
          main {
              manifest.srcFile 'AndroidManifest.xml'
              java.srcDirs = ['src']
              resources.srcDirs = ['src']
              aidl.srcDirs = ['src']
              renderscript.srcDirs = ['src']
              res.srcDirs = ['res']
              assets.srcDirs = ['assets']
           }
           androidTest.setRoot('tests')
        }
    }

     buildTypes {
       debug {
           // 移除无用的Resourcesw文件
           shrinkResources false
           // Zipalign优化
           zipAlignEnabled false
           // 混淆
           minifyEnabled false
           // 自定义BuildConfig
           buildConfigField "boolean", "LOG_DEBUG", "true"
       }
       release {
           // 移除无用的Resources文件
           shrinkResources true
           // Zipalign优化
           zipAlignEnabled true
           // 混淆
           minifyEnabled false
           // 自定义BuildConfig
           buildConfigField "boolean", "LOG_DEBUG", "false"
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
       }
   }

    // 系统将在lib目录下搜索依赖,如果不配置compile(name: 'vlc-android-sdk', ext: 'aar')编译将报错
    repositories {
        flatDir {
            dirs 'libs'
        }
    }

    // 移除lint检查的error
    lintOptions {
        abortOnError false
    }

    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    // 配置多渠道,三个包除了文件名没有什么不一样,因为我们还没有定制
    // 使用的都是defaultConfig配置。这里的flavor和defaultConfig是一样的,
    // 可以自定义其applicationId、versionCode以及versionName等信息,比如区分不同包名
    productFlavors {
        dev{
            applicationId rootProject.ext.applicationId + ".dev"// 覆盖包名
        }
        google{
            applicationId rootProject.ext.applicationId + ".google"
        }
        baidu{
            applicationId rootProject.ext.applicationId + ".baidu"
        }
    }

    // 使用manifestPlaceholders改变<meta-data>(编译时动态设置Android Manifest)
    // AndroidManifest.xml 文件中的占位符:
    //    <meta-data android:name="APPKEY" android:value="${app_key}"/>
    //    <meta-data android:name="SECRET" android:value="${app_secret}"/>
    productFlavors.all { flavor ->
        if (name.toLowerCase().equals('dev')) {
            flavor.manifestPlaceholders = [app_key: "测试用key", app_secret : "测试用secret"]
        } else {
            flavor.manifestPlaceholders = [app_key: "正式版key", app_secret : "正式版secret"]
        }
    }

    // 批量修改生成的apk文件名
    // 在我们打包发版的时候,一次性打几十个包,这时候我们就想让生成的apk文件名有区分,
    // 比如一眼就能看出这个apk是哪个版本的,哪个渠道的,是哪天打的包等等,
    // 这就需要我们在生成apk文件的时候动态修改生成的apk文件名达到这一目的。
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            if (output.outputFile != null
                    && output.outputFile.name.endsWith('.apk')
                    &&'release'.equals(variant.buildType.name)) {
                def outputName = "${variant.applicationId}" +
                        "_release" +
                        "_v${variant.versionName}" +
                        "_${buildTime()}.apk"
                output.outputFile = new File(output.outputFile.getParent(), outputName)
            }
        }
    }
}

def buildTime() {
    def date = new Date()
    def formattedDate = date.format('yyyyMMdd')
    return formattedDate
}

// 这个也就是所谓的依赖
dependencies {
    // 编译libs目录下的所有jar包,本地依赖
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    // 远程依赖
    compile 'com.android.support:appcompat-v7:22.+'
    compile 'com.android.support:recyclerview-v7:22.+'
    compile 'com.android.support:cardview-v7:22.+'
    compile 'com.android.support:design:22.+'
    testCompile 'junit:junit:4.11'
    // 编译aar
    compile(name: 'vlc-android-sdk', ext: 'aar')
    compile 'com.tencent.bugly:crashreport:latest.release'
    compile 'com.tencent.bugly:nativecrashreport:latest.release'
    // 编译extras目录下的ShimmerAndroid模块
    compile project(':extras:ShimmerAndroid')
}

“/build.gradle”

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

ext {
    compileSdkVersion = 22
    buildToolsVersion = '23.0.3'
    applicationId = 'cn.toltech.treefrog'
    minSdkVersion = 16
    targetSdkVersion = 19
    versionCode = 9
    versionName = "1.0.8.0"
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

打包的apk结果如下:
这里写图片描述

gradle-wrapper.properties

这里写图片描述

注意上面框框中gradle的版本要与:
这里写图片描述
中的一致。如果可以翻墙AS会自动下载对应版本到C盘的这个目录下,不用翻墙可以自己手动下载后放到对应目录。

配置应用的签名信息

在android.signingConfigs{}下定义一个或者多个签名信息,然后在buildTypes{}配置使用即可。如下:

android {

    signingConfigs {
        release {
            storeFile file("release.keystore")
            keyAlias "release"
            keyPassword "123456"
            storePassword "123456"
        }
        debug {
            ...
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }
  }

storeFile是签名证书文件,keyAlias是别名,keyPassword是key的密码,storePassword是证书的密码。配好好相关信息即可在buildTypes配置使用。

补充:flavorDimensions渠道维度


...

    buildTypes {
        debug {
            ...
        }
        release {
            ...
        }
    }

    flavorDimensions "target", "market"

    productFlavors {
        // 手机、平板、电视版
        phone {
            dimension "target"
            applicationId rootProject.ext.applicationId + ".phone"
            minSdkVersion 17
            versionCode = 1
            buildConfigField "boolean", "tv", "true"
        }
        pad {
            dimension "target"
            applicationId rootProject.ext.applicationId + ".pad"
            minSdkVersion 17
            versionCode = 1
            buildConfigField "boolean", "tv", "true"
        }
        tv {
            dimension "target"
            applicationId rootProject.ext.applicationId + ".tv"
            minSdkVersion 19
            versionCode = 2
            buildConfigField "boolean", "tv", "false"
        }

        // 谷歌、百度等手机助手市场
        google {
            dimension "market"
            buildConfigField "String", "URL", "\"https://www.google.api.com\""
        }
        baidu {
            dimension "market"
            buildConfigField "String", "URL", "\"https://www.baidu.api.com\""
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            if (output.outputFile != null
                    && output.outputFile.name.endsWith('.apk')
                    && 'release'.equals(variant.buildType.name)) {
                def market = '';
                if (variant.productFlavors.get(1).name.equals('google'))
                    market = 'google'
                else if (variant.productFlavors.get(1).name.equals('baidu'))
                    market = 'baidu'
                else if (variant.productFlavors.get(1).name.equals('tencent'))
                    market = 'tencent'
                def outputName = "${variant.applicationId}" +
                        "_${market}" +
                        "_release" +
                        "_v${variant.versionName}" +
                        "_${buildTime()}.apk"
                output.outputFile = new File(output.outputFile.getParent(), outputName)
            }
        }
    }
}

def buildTime() {
    def date = new Date()
    def formattedDate = date.format('yyyyMMdd')
    return formattedDate
}


...

生成的variants(2个buildType*3个target维度*2个market维度=12):

打包的apk结果如下:
这里写图片描述

常见错误

1、

Gradle: FAILURE: Could not determine which tasks to execute.

  • What went wrong: Task ‘assemble’ not found in root project ‘MyProject’.

  • Try: Run gradle tasks to get a list of available tasks.

解决办法:
这里写图片描述
删除框框中所有节点的数据,重新build一下。

2、提示AIDL文件中的类找不到,导致gradle失败:
这里写图片描述
解决办法:
手动在compileSdkVersion 编译版本对应的framework.aidl文件末尾加上这些类,如下图:
这里写图片描述

3、从Eclipse ADT中导过来的项目,发现无法build,app module找不到,可以手动在.ideal/modules.xml文件中加上:
这里写图片描述

4、从别的地方考进来一个java类,gradle编译时,文件没有任何错误,但总是编译失败,出现错误如下错误信息:

Execution failed for task ':TestAndroid:compileDebug'.
Compilation failed; see the compiler error output for details.

解决办法:文件的编码与Gradle默认编译采用的编码不一致。将文件的内容的编码改为gradle工程编译的编码,再拷进来。

还可以在gradle配置文件加入:
//设置编码
tasks.withType(Compile) {
options.encoding = “UTF-8”
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值