Android开发之Gradle笔记整理1

news/2024/5/20 2:51:29 标签: android, gradle, 多渠道打包

在Android开发中,我们经常会涉及到打包的问题,不管是debug包还是release包或者是beta包,又或是形形色色的各种国内的应用市场,即使是常见的应用市场,也不下几十个,所以打包的时候尤其痛苦,好在我们有Gradle。当然,看过美团的Android项目打包方案,也是一个不错的选择,感兴趣的同学也同样可以研究一下:美团Android自动化之旅—生成渠道包

gradle是啥" style="font-size:14.44444465637207px; font-weight:100; margin:0.8em 0px; color:rgb(51,51,51); font-family:'microsoft yahei'; line-height:25.98958396911621px"> Gradle是啥?

Gradle是一个依赖管理工具,基于Groovy语言,面向java应用为主,它抛弃了各种基于XML的繁琐配置,取而代之的时基于Groovy的内部领域特定语言,即DSL语言。

gradle安装" style="font-size:14.44444465637207px; font-weight:100; margin:0.8em 0px; color:rgb(51,51,51); font-family:'microsoft yahei'; line-height:25.98958396911621px"> Gradle安装

在Mac下,安装了Idea并且启用了Gradle支持的话,首次创建Gradle: Android Module的时候会自动下载Gradle,最好翻墙下载,速度会快一些,当然不翻墙也可以成功下载。

img

下载之后的Gradle保存在 shell /Users/EricTang/.gradle

gradle快速入门" style="font-size:14.44444465637207px; font-weight:100; margin:0.8em 0px; color:rgb(51,51,51); font-family:'microsoft yahei'; line-height:25.98958396911621px"> Gradle快速入门

我们随便新建一个项目,命名为GradleTest,然后我们看一下Gradle的相关配置文件,跟Gradle配置相关的文件主要有: 
一、 GradleTest/GradleTest/build.gradle

img

此处的build.gradle是整个Module的Gradle配置文件,也是主要的Gradle配置文件,然后我们看一下主Gradle配置文件的内容以及注释:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.1'
    }
}
//声明这是Android应用程序
apply plugin: 'com.android.application'

repositories {
    jcenter()
}

android {
        // 编译的SDK版本
        compileSdkVersion 19
        // buildTools的版本
        buildToolsVersion "21.1.1"

    defaultConfig {
        // 应用包名
        applicationId "com.aiscot.gradle.test"
        minSdkVersion 9
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    // java版本
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    buildTypes {
        debug {
            // debug模式
        }
        release {
            // release模式
            // 是否进行混淆
            minifyEnabled false
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    // 将项目中libs目录下的所有jar包包含到编译目录中
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
}


几点注意事项:

  1. apply plugin是最新的Gradle版本写法,之前的版本写法是apply plugin: “android”,以前使用过的同学记得改正过来,刚开始用的同学(比如我)算是比较幸运的,可以直接从新的语法开始写起

  2. buildToolsVersion需要本地的SDK里安装过的版本才行,这个可以手动更改,或者通过Android SDK Manager下载相对应的版本

  3. sourceCompatibility后面的JavaVersion.VERSION_1_X指的是编译项目所需的java版本,Mac系统在10.9之前都是自带JDK1.6的,但是从10.9开始,java就不是Mac系统的一等公民了,不默认安装,这点我想大家在运行Idea或者Eclipse之类的IDE的时候应该已经知道了,运行的时候会提示你当前没有安装JDK,点击更多信息之后会跳转到Apple的Support网站去下载。不过还需要注意一点,最好把JDK1.7或者JDK1.8安装上,因为Android从5.0开始需要JDK1.7才能进行编译

  4. 创建Gradle Android项目之后,自动生成的是默认基本配置,当然还有很多其他的自定义部分,例如自动打包debug、release、beta等,签名,多渠道打包等。

二、 GradleTest/build.gradle

img

img

Idea中每个Project相当于一个Workspace,而一个Module相当于一个Project,我们的Android项目中肯定有一个是运行的,而其他的Module就是引用的Library,每个Module(不论是运行的工程还是引用的Library)都需要有一个gradle配置文件,语法都是一样的,唯一不同的是开头声明的:运行的工程师开头声明的是“apply plugin:’com.android.application’”,而引用的Library开头声明的则是“apply plugin:’com.android.library’”

上面这个文件,就是整个Project的gradle基础配置文件,我们来看一下它的内容:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

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

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}


该文件主要包含两个方面的内容:

  1. jcenter(),这里可以理解为一个新的中央远程仓库,兼容maven中心仓库,但是性能更优。

  2. classpath,声明了android gradle plugin的版本,这里的版本,对Idea的版本没有什么特殊要求,我用的是Idea14的版本,完全正常使用,其他的IDE例如Eclipse和Android Studio我就不是很清楚了。

三、 GradleTest/gradle目录 
这个目录下面有个wrapper目录,里面有两个文件,一个是gradle-wrapper.jar,另一个是gradle-wrapper.properties文件,这里我们重点看一下gradle-wrapper.properties文件的内容:

#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip


这里面声明了Gradle的目录、下载路径以及当前项目所使用的Gradle版本,一般情况下保持默认即可,无需更改,不过如果项目报错的话,而且确实是Gradle版本问题的话,我们也可以通过手动修改指定到正确的路径。

四、 GradleTest/settings.gradle文件

img

该文件是全局的项目配置文件,内容如下:

include ':GradleTest'

里面主要是生命一些需要加入Gradle的Module,例如我们这里就暂时就只有一个,如果引用了其他的Module,就按照  include ':GradleTest’, ‘extras:额外的Module’  的格式加入进去即可

其它问题

一、有些同学会和我一样,对Gradle的sync不是很熟悉,嗯,是这样儿的,每次我们修改了build.gradle文件,Gradle项目需要与Idea进行文件同步,点击sync now之后,Idea会根据Gradle文件重新更新.idea目录以及*.iml文件,让Idea可以识别到新引入的资源。

二、关于Module中的build.gradle文件的buildscript代码其实是可以删除掉的,因为它可以从父项目中继承得来,即,使用GradleTest/build.gradle处的设置

img

三、关于“Gradle: Error retrieving parent for item: No resources found that matches the given name ‘android:TextAppearance.Material’”的错误

img

如果遇到这个错误的话,你就需要检查一下你相应的Module中得dependencies,确保将compile ‘com.android.support:appcompat-v7:22.0.0’的写法修正为’com.android.support:appcompat-v7:19.+’,这里的19指的是SDK版本号,需要跟你的targetSdkVersion保持一致。

参考链接:Error retrieving parent for item - Android Studio

四、Gradle的sync在无网络连接的情况下失效

这个可以通过设置Gradle的离线工作方式来解决,打开Preferences,在Build, Execution, Deployment下的Build Tools中找到Gradle。

img

勾选Offline work即可。

关于Gradle的快速入门先写这么多,然后后面会重点记录一下多渠道打包的问题


Gradle常用命令及UMeng多渠道打包实战 

小小的实践一下,本身也是在Android开发中必不可少的技能。

gradle文件" style="font-weight:100; margin:0.8em 0px; color:rgb(51,51,51); font-family:'microsoft yahei'; line-height:25.98958396911621px"> 修改build.gradle文件

接着之前的项目继续看,我们修改一下Module中的build.gradle文件,这里也不做过多讲解了,注释都在文件中,慢慢看,还是比较容易懂的:

apply plugin: 'com.android.application'

repositories {
    jcenter()
}

android {
    compileSdkVersion 19
    buildToolsVersion "21.1.1"

    defaultConfig {
        applicationId "com.aiscot.gradle.test"
        minSdkVersion 9
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"

        // 修改dex 65536的限制
        multiDexEnabled true
        // AndroidManifest.xml文件中UMENG_CHANNEL的value为${UMENG_CHANNEL_VALUE}
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "channel_name"]
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    // 签名文件
    signingConfigs {
        debug {
            // debug签名
            storeFile file("/path/xx-debug.jks")
            storePassword "密码"
            keyAlias "别名"
            keyPassword "签名密钥的密码"
        }
        release {
            // relase签名
            storeFile file("/path/xx-release.jks")
            storePassword "密码"
            keyAlias "别名"
            keyPassword "签名密钥的密码"
        }
    }

    // 构建类型
    buildTypes {
        debug {
            // debug模式下,显示log
            buildConfigField("boolean", "LOG_DEBUG", "true")

            // 版本名前缀
            versionNameSuffix "-debug"
            // 不开启混淆
            minifyEnabled false
            // 不开启ZipAlign优化
            zipAlignEnabled false
            // 不移除无用的resource文件
            shrinkResources false
            // 使用debug签名
            signingConfig signingConfigs.debug

        }
        release {
            // release模式下,不显示log
            buildConfigField("boolean", "LOG_DEBUG", "false")

            // 版本名前缀
            versionNameSuffix "-relase"
            // 开启混淆
            minifyEnabled true
            // 开启ZipAlign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            // 使用release签名
            signingConfig signingConfigs.release
            // 混淆文件位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    // 渠道Flavors,配置不同的渠道
    productFlavors {
        GooglePaly {}
        xiaomi {}
        umeng {}
        _360 {}
        wandoujia {}
        yingyongbao {}
        whatever {}
    }

    // 批量配置渠道
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }

    applicationVariants.all {
        variant ->
            variant.outputs.each {
                output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
            }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:19.+'
}


重点需要讲解的地方:

  1. signingConfigs中的debug签名和release签名,都可以写绝对路径,当然,也可以通过指定形如debug{storeFile file("xx-debug.jks")}这样儿的配置,只不过需要注意,如果使用这样儿的方式,签名文件需要放在项目中

  2. UMeng官方的多渠道打包集成文档中指定,如果使用Gradle打包的方式的话,需要在build.gradle文件中的dependencies中添加如下的依赖:

     dependencies {
            compile 'com.umeng.analytics:analytics:latest.integration'
        }

    这里我的想法是,build.grade文件中已经包含了libs目录下所有的jar包了

     compile fileTree(dir: 'libs', include: ['*.jar'])

所以我们其实可以直接把UMeng的jar包丢到这个目录下即可(写这篇博客的时候,我并不是很确定,写完了之后,测试完了,是正常的,所以这里应该是没有问题的,暂时没有做进一步的研究)

集成UMeng统计
  1. 配置manifest文件,UMeng的渠道统计需要在manifest文件中添加权限,注意,需要跟应用中已有的全选做下对比,避免重复 、
  <!-- UMeng统计所需权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <!-- UMeng统计所需权限 -->

同时,还需要加入UMeng的AppKey,和Channel ID,需要注意的是,这里的UMENG_CHANNEL的value需要写成  ${UMENG_CHANNEL_VALUE} ,因为我们需要在build.gradle文件中对其进行操作,自动替换的
<!-- UMeng统计的Key和Channel -->
    <meta-data android:name=“UMENG_APPKEY” android:value="APPKEY"/>
    <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/>
    <!-- UMeng统计的Key和Channel -->

然后需要在每个Activity的onResume方法中调用MobclickAgent.onResume(Context), onPause方法中调用MobclickAgent.onPause(Context)

然后看我们在build.gradle文件中的配置:
// 渠道Flavors,配置不同的渠道
    productFlavors {
        GooglePaly {}
        xiaomi {}
        umeng {}
        _360 {}
        wandoujia {}
        yingyongbao {}
    }
    // 批量配置渠道
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }


然后关于UMeng的多渠道配置就基本完成了,接下来我们需要做的,就是了解Gradle的常用命令,并且进行打包操作了。
gradle自动打包" style="font-weight:100; margin:0.8em 0px; color:rgb(51,51,51); font-family:'microsoft yahei'; line-height:25.98958396911621px"> Gradle自动打包

打开终端,cd到Gradle项目所在的目录,啊?等下,我们用的是Idea啊,没必要的啊,来,跟我来,找到Idea项目界面最下方:

img

看到Terminal的字样了么?点它

img

自然就已经在项目的根目录下了

这时候,我们只需要执行 ./gradlew assembleRelease 命令,就可以完成release版本的各渠道的打包工作了,这里需要注意的是,如果是第一次执行该命令的话,会自动去下载Gradle。。额,没错儿,是自动去下载,即使是我们已经下载安装过Gradle了。。所以第一次的话,可能时间稍长,当时我测试的情况是6个渠道包,大概耗时3分35秒左右的样子,后面的话就会快很多了,大概耗时10秒左右。

其他的命令还有:

  1. ./gradlew assembleDebug —— 打包debug版本

  2. ./gradlew assembleXiaomiRelease —— 单独打包小米应用市场渠道的release版本

  3. ./gradlew assembleXiaomi —— 单独打包小米应用市场渠道的debug和release版本

关于Gradle多渠道打包的就暂时先写到这里,如果到时候渠道包太多,觉得Gradle速度太慢每次都要构建一次的话,也确实可以参考美团的打包方案,也是可行的。



http://www.niftyadmin.cn/n/1678133.html

相关文章

centos6.5 下的vim的python自动补全

(1)yum install -y vim(2)安装:wget https://github.com/rkulla/pydiction/archive/master.zipunzip -q mastermv pydiction-master pydictionmkdir -p ~/.vim/tools/pydictioncp -r pydiction/after ~/.vimcp pydiction/complete-dict ~/.vim/tools/pydiction确保文件结构如下…

这一路~~jncip

开始想学学JUNIPER是因为搞IP Telephony太久了&#xff0c;碰巧2010年中又开始做一个安全的项目&#xff0c;项目之间的时间很充裕&#xff0c;觉得应该再扩展一下。对比几个JUNIPER的培训机构&#xff0c;汤姆一通无疑是最好的&#xff0c;不仅她能提供JUNIPER的整体学习环境&…

12条有用的Flex代码

1.复制内容到系统剪贴板 System.setClipboard(strContent); 2.复制一个ArrayCollection //dummy solution( well, it works ) var bar:ArrayCollection new ArrayCollection(); for each ( var i:Object in ac ){ bar.addItem( i ); } // fantastic ! //…

设置分页页码

/// <summary>/// 设置分页页码/// </summary>/// <param name"pageNum">当前页码</param>/// <param name"pageCount">总页数</param>/// <param name"sideNum">每页显示条数</param>/// <…

SSH整合2

目录工程结构配置文件工程结构 开始写实体类 ArticlesBizImpl package com.yinyi.vue.biz.impl;import java.util.List; import java.util.Map;import com.yinyi.base.uitl.PageBean; import com.yinyi.vue.biz.ArticlesBiz; import com.yinyi.vue.dao.ArticlesDao; import co…

Android开发之Gradle笔记整理2

在使用gradle命令执行打包apk时&#xff0c;需要在build文件中配置签名&#xff0c; signingConfigs { //签名&#xff0c;这里的文件名和密码是错的&#xff0c;后面还会有从外部导入的语句debug {storeFile file("./MyApplication5.jks") //签名文件storePa…

IIS配置

步骤 &#xff1a; 安装和配置 Windows Server 2003。 1. 将\System32\cmd.exe转移到其他目录或更名&#xff1b; 2. 系统帐号尽量少&#xff0c;更改默认帐户名&#xff08;如Administrator&#xff09;和描述&#xff0c;密码尽量复杂&#xff1b; 3. 拒绝通过网络访问该计…

Hover伪类在IE6中的实现

鼠标滑过行&#xff0c;行改变颜色可以使用javascript写&#xff0c;onmouseover&#xff0c;onmouseout&#xff0c;也可以使用css2的伪类hover&#xff0c;但是ie6对伪类支持的不好&#xff0c;需要变换一下思路&#xff0c;要么使用javascript&#xff0c;onmouseover就变为…