Android 之Gradle教程

一、什么是Gradle

          Gradle是一个工具,同时它也是一个编程框架.。可以调用Gradle自带的api编译我们的Android工程,打包成apk或aar,也可以在.gradle文件中使用Groovy语言进行逻辑编程。我们在android工程中使用的每个.gradle文件 和task执行时都会转换成一个个的java对象,运行在java虚拟机上。其中主要的有Gradle对象、Project对象和Settings对象。

二、实践

     后面我们通过配置和创建属性文件实现以下几个任务:

     1、实现多渠道打包

     2、通过文件方式配置版本号 及版本名等信息

     3、通过文件方式配置签名文件

     4、根据不同渠道动态修改程序名称和包名

     5、根据不同渠道生成apk文件名称及自定义文件输出路径

     6、根据不同渠道定制专属页面

    在实现任务之前 先要说几个基础知识:

      1、声明变量

           Gradle中声明变量有三种方式  一种是 通过def关键字  如 def a =1 ,这种声明只能在声明所在的方法中使用相当于临时变量,原因后面会详细说下,另一种是 ext关键字 如ext.a = 1,这种方式是可以在外部声明在其中方法中使用的, 类似于我们成员变量,另外还有就是 直接声明  a =1,这种方式也可以在外部声明在其中方法中使用,但不能在文件外部调用,其实还有一种方式 和ext 效果一样,

1.  import groovy.transform.Field;   //必须要先import

2.  @Field x = 1

   这种方式 在我们android开发中基本不会使用  。

    2、定义方法

          定义方法 使用def 关键字

          如  def printName(name){

                      println “hello”+name  //结束没有 ;

                    }

          或 def  sayHello(){

                   println “hello”

                }

      3、调用方法

             调用方法可以用两种方式    比如  printName(“gqs”)   也可以  printName “gqs”

     下面直接贴  .gradle文件,所有的说明都穿插在代码中:

  1. //导入插件 真正工作的就是这些插件 gradle 只是设置使用规则
  2. //apply 其实也是一个方法,就是这样定义的
  3. //void apply(Map<String, ?> options);
  4. apply plugin: ‘com.android.application’
  5. // 默认版本号
  6. ext.appVersionCode = 1
  7. // 默认版本名z
  8. ext.appVersionName = “1.0”
  9. // 默认apk输出路径
  10.  ext.appReleaseDir = “../apks”
  11. // 默认正式包后缀名
  12. ext.appSuffixName = “_release.apk”
  13. // 也可以向下面这种方式声明变量
  14. ext{
  15.     a =1
  16.     b = 2
  17. }
  18. //定义一个测试方法
  19. def printName(name){
  20.     println “hello====” +name
  21. }
  22. //可以如下调用
  23. printName “gqs”
  24. //printName(“gqs”)
  25. ////定义一个方法   获取当前日期
  26. def getPackageTime() {
  27.     def date = new Date()
  28.     def formattedDate = date.format(‘yyyy_MM_dd_HHmm’)
  29.     return formattedDate
  30. }
  31. // 加载版本信息配置文件方法
  32. def loadProperties() {
  33.     //将我们的版本号等信息配置在了local.properties 文件中,这里的file() 是一个方法,返回一个File对象
  34.     def proFile = file(“../local.properties”)
  35.     //Properties 是一种数据类型,其实是就是继承自hashtable , 可以解析.properties文件,并以键值对方式存储起来
  36.     //public class Properties extends Hashtable
  37.     Properties pro = new Properties()
  38.     proFile.withInputStream { stream->
  39.         pro.load(stream)
  40.     }
  41.     //为上面定义的变量赋值
  42.     appReleaseDir = pro.appReleaseDir
  43.     appVersionCode = Integer.valueOf(pro.appVersionCode)
  44.     appVersionName = pro.appVersionName
  45.     appSuffixName = pro.appSuffixName
  46. }
  47.    // 调用方法 加载版本信息
  48.   loadProperties()
  49.   android {
  50.     compileSdkVersion 24
  51.     buildToolsVersion “24.0.0”
  52.     defaultConfig {
  53.         applicationId “com.gqs.demo”
  54.         minSdkVersion 14
  55.         targetSdkVersion 24
  56.         versionCode appVersionCode
  57.         versionName appVersionName
  58.         testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”
  59.     }
  60.       // 到这里就完成了 任务 2 通过文件方式配置版本号 及版本名等信息
  61.       //signingConfigs 是对签名文件的配置 使用时会转成一个java方法
  62.     signingConfigs {
  63.         debug {
  64.         }
  65.         release {
  66.             def Properties localProps = new Properties()
  67.             //signature.properties 是配置签名信息的配置文件 后面会贴出来
  68.             localProps.load(new FileInputStream(file(‘../signature.properties’)))
  69.             storeFile file(localProps[“STORE_FILE”])
  70.             keyAlias localProps[“KEY_ALIAS”]
  71.             storePassword localProps[“STORE_PASSWORD”]
  72.             keyPassword localProps[“KEY_PASSWORD”]
  73.         }
  74.     }
  75.       // 到这里就完成了 任务 3 通过文件方式配置签名文件
  76.       //buildTypes 对不同的打包类型 进行配置
  77.     buildTypes {
  78.         release {
  79.             minifyEnabled true //实现代码混淆
  80.             signingConfig signingConfigs.release  //使用的签名信息
  81.             proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
  82.             applicationVariants.all { variant ->
  83.                 variant.outputs.each { output ->
  84.                     //开始输出,自定义输出路径
  85.                     output.outputFile =
  86.                             new File(appReleaseDir + getPackageTime() + //获取当前日期
  87.                                     “_v” + appVersionName +//每一个渠道的名称
  88.                                     variant.productFlavors[0].name +
  89.                                     appSuffixName)//appSuffixName 是我们声明的文件后缀
  90.                 }
  91.             }
  92.         }
  93.     }
  94. // 到这里 就实现了 任务 5 根据不同渠道生成apk文件名称及自定义文件输出路径
  95.       //productFlavors  就是实现不同渠道打包了
  96.     productFlavors {
  97.         //对每个渠道 设定特定的包名  也就是applicationId
  98.         rainbow{
  99.            // 都使用默认设置
  100.         }
  101.         xiaomi {
  102.             //设置特定渠道的包名
  103.             applicationId “com.rainbow.xiaomi”
  104.         }
  105.         m360 {
  106.             applicationId “com.rainbow.qihu”
  107.         }
  108.         productFlavors.all { flavor ->
  109.             //动态设置不同渠道的app name
  110.             // AndroidManifest文件中  android:label=”${APP_NAME}”
  111.             //使用渠道名称替换 APP_NAME,使每个渠道都有自己的 app名称
  112.             flavor.manifestPlaceholders = [APP_NAME: name]
  113.         }
  114.         //这样 我们就完成了任务 1 和4 ;多渠道打包及根据不同渠道动态修改程序名称和包名
  115.     }
  116. }
  117. dependencies {
  118.     compile fileTree(dir: ‘libs’, include: [‘*.jar’])
  119.     androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2’, {
  120.         exclude group: ‘com.android.support’, module: ‘support-annotations’
  121.     })
  122.     testCompile ‘junit:junit:4.12’
  123. }

下面是signature.properties文件

  1. // 设置 签名文件的信息,用键值对的格式存放
  2. //注意 为了安全,不要放到版本管理里面
  3. //STORE_FILE 签名文件相对地址,这个地址是相对我们使用的所在位置,不是相对当前文件位置
  4. STORE_FILE=../debug.keystore
  5. STORE_PASSWORD=android
  6. KEY_ALIAS=androiddebugkey
  7. KEY_PASSWORD=android

===========================

   下面是local.properties
  1. ## This file is automatically generated by Android Studio.
  2. # Do not modify this file — YOUR CHANGES WILL BE ERASED!
  3. #
  4. # This file should *NOT* be checked into Version Control Systems,
  5. # as it contains information specific to your local configuration.
  6. #
  7. # Location of the SDK. This is only used by Gradle.
  8. # For customization when using a Version Control System, please read the
  9. # header note.
  10. sdk.dir=/Applications/android_tools/android-sdk-macosx
  11. #=====以下是自己定义的内容=====
  12. # 打包的输出路径
  13. appReleaseDir=./apks/
  14. # APP版本号,用来升级使用
  15. appVersionCode=2
  16. # APP版本名称,最终打包使用
  17. appVersionName=1.0.0.2
  18. # app正式版包名后缀
  19. appSuffixName=_release.apk

    最后 实现 任务6 根据不同渠道定制专属页面

   只要在我们的 src文件夹下 创建和渠道相同的文件夹 可以了 ,里面放入我们要修改的布局文件或values中的文件。

 其实默认 我们用的都是 src下 main中的文件 ,如果我们创建了和渠道名称相同的文件夹 ,gradle 打包的时候 就会从对应到文件夹中取数据了。

 

    比如我替换了 首页的布局 ,同一个应用根据不同渠道最后就生成了三个不同的页面

    screenshot_2016-10-21-12-12-48-790_m360 screenshot_2016-10-21-12-12-42-076_xiaomi screenshot_2016-10-21-12-12-35-625_rainbow screenshot_2016-10-21-12-12-30-682_%e6%a1%8c%e9%9d%a2

    以上就是所有了,总之Gradle 是非常强大的,只要你想 ,可以实现你各种需求,当然对于android 开发终归只是辅助工具,不必理解的过于深入,但是熟练掌握基本的使用是必须的,这可以大大的提高我们到开发效率。

 代码地址 点击打开链接

发表评论