gradle的学习与实践记录(一)

已经很久都没有来写笔记了,最近看见6月25日的直播大会,同时看见以前写的笔记,还有人评论,也就动笔来写一写,其实将近半年了,这半年来,也有很多的东西需要记录,因为时间过了,一切也就很快忘记了。

这篇笔记,是我整理当中的其中一篇,也希望最近利用周末,好好做做梳理。

一、gradle的编译目录,与项目目录结构的更改。

gradle的资源路径默认一般都是固定的

/src/main/java/*
/src/test/java/*

上面的两个地址,就是gradle编译的默认路径,也就是说我们再不编辑sourceSets的情况下,只有这里面的代码才会被编辑, test中的是测试代码。

sourceSets{} 是gradle中的dsl区域语言,形同这样的dsl区域语言还有很多,如下图:

这里写图片描述

我们可以通过这个地址:android-gradle-dsl来进行学习

sourceSets{}是专用来修改gradle的默认编译目录的。

sourceSets {
        main {
            res.srcDirs = ['src/main/res',
                           'src/main/res/layout/activity/',
                           'src/main/res/layout/fragment/',
                           'src/main/res/layout/rvitem/',
                           'src/main/res/layout/lvitem/']
            assets.srcDirs = ['src/main/assets']
            java.srcDirs = ['/src/main/java']
            resources.srcDirs = ['src/main/resources']
        }
    }

main当中,res.srcDirs是用来指定要编译项目的资源文件,assets.srcDirs是用来指定要放的第三方库文件,java.srcDirs当然是我们写的代码,resources.srcDirs好像也是指定资源的,要和res.srcDirs配合。

其中我定义了四个扩展的专用放布局的文件夹,一看也就不用我说他们的用途了。

这里写图片描述

比较详细的文章:大头鬼Bruce的深入浅出Android Gradle构建系统(二:项目结构)

二.Gradle的全局配置(依赖统一管理)

在项目根目录,新建config.gradle文件,用它来进行全局配置。

这里写图片描述

也就是,我们可以把版本配置和,依赖,与key值,用到这里面进行配置。

使用时,导入,进行使用就行了

这里写图片描述

下面的使用方法,对Module也是一样的

这里写图片描述
这里写图片描述
这里写图片描述

比较详细的文章:QDJdeveloper写的 Android 使用 Gradle 统一配置依赖管理

三、签名配置

签名配置,就是对apk进行签名吗,就像我们打包,要输入的密码一样,只是我们配置在gradle的命令中,写死了签名,一般 在android 中写,他是我们用命令打包和多渠道打包,必须配置的。

使用signingConfigs {}dsl区域语言。

  signingConfigs {
          release {
              //  ../表示根目录
              storeFile file("../gradleadb.jks")指定目录也可是('H:\\*\\*.keystore')
              storePassword "android"  
              keyAlias "张荣"
              keyPassword "android"
          }
  }
  在buildTypes中release内加入 signingConfig signingConfigs.release  //使用签名
   buildTypes {

          release {

              signingConfig signingConfigs.release  //使用签名
          }
    }

完整的:

android{
*****
 signingConfigs {
          release {
              //  ../表示根目录
              storeFile file("../gradleadb.jks")指定目录也可是('H:\\*\\*.keystore')
              storePassword "android"  
              keyAlias "张荣"
              keyPassword "android"
          }
          xiaozhang {
            //gradle.properties 动态设置签名参数
            storeFile file(System.properties['keyStore'])
            storePassword System.properties['storePassword'] //取storePassword值
            keyAlias System.properties['keyAlias']
            keyPassword System.properties['keyPassword']
        }
  }
  buildTypes {
       release {
            minifyEnabled true //开启混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            shrinkResources true//踢掉无用资源
            zipAlignEnabled true //是否zip优化
            manifestPlaceholders = [AMAP_KEY: parent.ext.key.AMAP_RELEASE_KEY] //Gradle key配置
            signingConfig signingConfigs.release  //使用签名
        }
        debug {
            debuggable true  // 是否保留调试信息
            minifyEnabled false
            applicationIdSuffix '.debug'//包名加后缀
            manifestPlaceholders = [AMAP_KEY: parent.ext.key.AMAP_DEBUG_KEY]//Gradle key配置
            signingConfig signingConfigs.release  //使用签名
        }
        //自定义构造 app打包方式  会在 app\build\outputs\apk 下面生成app-xiaozhang-unsigned.apk
//        xiaozhang.initWith(buildTypes.debug)
        xiaozhang {
            manifestPlaceholders = [AMAP_KEY: parent.ext.key.AMAP_RELEASE_KEY] //Gradle key配置
            applicationIdSuffix '.xiaozhang'
//            signingConfig signingConfigs.xiaozhang  //使用签名
        }
  }

****
}

四、多渠道打包配置

使用productFlavors{}dsl区域语言,进行渠道配置,然后用applicationVariants.all{}进行打包修改名字。名字一定不能重复,不然打包时就覆盖了

1.不要渠道号,直接配置的

productFlavors {

        productBaidu
        product360
        productHuaWei
        productMeiZu
    }
 //渠道打包命名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
                    && 'release'.equals(variant.buildType.name)) {
                def apkFile = new File(output.outputFile.getParent(),
                        "cxb_${variant.flavorName}_ver${variant.versionName}.apk")
                output.outputFile = apkFile
            }
        }
    }
    也可以这样:
     android.applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    //这里修改apk文件名
                    def fileName = "网约车司机端" + "_" + variant.productFlavors[0].name +
                            defaultConfig.versionName + "_" + variant.buildType.name + ".apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
     反正这里,自行配置。

2.带渠道号的,有两种处理办法。一是用buildConfig变量来,一是用manifestPlaceholders属性来。

用buildConfig变量:

 productFlavors {
        defult {
            buildConfigField "int", "APP_CHANNEL", "11" //配置一个APP_CHANNEL int变量
        }
        qh360 {
            buildConfigField "int", "APP_CHANNEL", "12"
        }
        baidu {
            buildConfigField "int", "APP_CHANNEL", "13"
        }
        yingyongbao {
            buildConfigField "int", "APP_CHANNEL", "14"
        }
    }
  //打包命令是一样的  
 android.applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def outputFile = output.outputFile
                if (outputFile != null && outputFile.name.endsWith('.apk')) {
                    //这里修改apk文件名
                    def fileName = "网约车司机端" + "_" + variant.productFlavors[0].name +
                            defaultConfig.versionName + "_" + variant.buildType.name + ".apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }    

在代码中,给接口传渠道号的话,就用这个方式获取。

这里写图片描述

用manifestPlaceholders属性来:

有些第三方要求必须处理渠道号,比如极光,友盟,需要统计。

1.配置Manifest 中meta-data属性

 友盟的统计:
 <meta-data
        android:name="UMENG_CHANNEL"
        android:value="Channel_ID" />
 修改为:
 <meta-data
        android:name="UMENG_CHANNEL"
        android:value="${CHANNEL_VALUE}" />

2.app build.gradle中进行配置

##defaultConfig{}里加上CHANNEL_VALUE的默认值:
defaultConfig {
        ...
        manifestPlaceholders = [ CHANNEL_VALUE:"default_channel" ]
    }
##productFlavors{}里这样配置:
productFlavors {   
        defult{}
        baidu_dsp{}
        baidu{}
        Tencent{}
        _360{}
        anzhi{}
        taoyingyong{}
        kuchuan{}
        *****
    }
    ##productFlavors.all 是一个遍历,每一个 productFlavors 中的值,其中productFlavors 的每一个值都有一个 name ,就是类似 baidu 这样的字符,每次循环的时候会替换掉 AndroidManifext.xml 中的${CHANNEL_VALUE}

 productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [CHANNEL_VALUE: name] 
    }

 //渠道打包命名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
                    && 'release'.equals(variant.buildType.name)) {
                def apkFile = new File(output.outputFile.getParent(),
                        "chexinbang_${variant.flavorName}_ver${variant.versionName}.apk")
                output.outputFile = apkFile
            }
        }
    }

在代码中,传给接口,用这样的方法去获取:

##定一个工具类,写一个方法。
/** 获取渠道id */
    public static String getDownSoure() {
        ApplicationInfo appInfo;
        String channelId = "30201";
        String channel = "guanwang";// = mapplication.getResources().getString(R.string.channel);
        try {
        appInfo =mapplication.getPackageManager().getApplicationInfo(mapplication.getApplicationContext().getPackageName(), PackageManager.GET_META_DATA);
            channel = "" + appInfo.metaData.get("UMENG_CHANNEL");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            channelId="30201";
        }

        switch (channel) {
            case "baidu_dsp" :
                channelId = "10102";
                break;
             case "baidu" :
                channelId = "10101";
                break;
             case "Tencent" :
                channelId = "10201";
                break;
             case "_360" :
                channelId = "10301";
                break;
             case "anzhi" :
                channelId = "10401";
                break;
             case "taoyingyong" :
                channelId = "10501";
                break;
             case "kuchuan" :
                channelId = "10601";
                break;
             case "jifeng" :
                channelId = "10701";
                break;
             case "wandoujia" :
                channelId = "10801";
                break;
            case "momo" :
                channelId = "10901";
                break;
             case "xiaomi" :
                channelId = "20101";
                break;
            case "huawei" :
                channelId = "20201";
                break;
            case "meizu" :
                channelId = "20301";
                break;
            case "oppo" :
                channelId = "20401";
                break;
            case "guanwang" :
                channelId = "30201";
                break;
        }

        return channelId;
    }

关于构建,比较详细的文章:使用Gradle构建Android应用的渠道包

后面还有一些精华的笔记,用第二篇来记载,太长了。

gradle的学习与实践记录(一) 整理记录完毕。

猜你喜欢

转载自blog.csdn.net/zr940326/article/details/73359963
今日推荐