美文网首页
Android多渠道打包--多维度

Android多渠道打包--多维度

作者: 费城的二鹏 | 来源:发表于2020-05-02 13:26 被阅读0次

    照片是 2020.05.01 花了半个小时用小米9专业模式拍出的效果,有点月色朦胧的味道。感觉到极客时间的摄影课没有白买,至少了解了一点摄影的基础知识。

    开端

    日常Android开发会有打出不同用途包的要求,最基本的就是给开发环境、测试环境和生产环境打出不同地址的包。以前都是在Java代码里写多个地址,打包时去注释切换不同的地址。例如:

    String url = "";
    url = "http://192.168.1.1/";     // 开发环境
    // url = "http://192.168.1.2/";     // 测试环境
    // url = "http://192.168.1.3/";     // 生产环境
    

    这样的方式有个问题,如果忘记改了那就打错包了,而且一次只能打出一个包。如果多个人开发,并且切换过不同的地址提交到git,还得解决冲突问题,特别的麻烦。

    以上就是我这个强迫症的动力源泉,就去万能的google搜索解决方案去了。说到这,还是要批评下自己,很多东西知道它的存在,但是没有亲自动手用过,影响就是需要用的时候不能直接上手,领导也不会让你直接用,还需要花时间学习使用。这也就是日常学习与练手的目的,知其然,知其所以然,还要能熟练运用。

    单维度

    上面的那个需求,只需要添加下面的配置,就可以将配置提到 gradle 内,在开发与打包时都可以通过选择版本来控制打包地址,甚至可以将三个包一同打出来。

    flavorDimensions "default"
    
    productFlavors {
        dev {
            buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
        }
    
        ftest {
            buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
        }
    
        pro {
            buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
        }
    }
    

    可以看到定义了三个地址,那么怎么在代码中运用呢?留意一下这个 BASE_URL 变量的名字,还有这个单引号嵌套双引号的写法。

    public static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient)
            .build();
    

    日常我们使用 Retrofit 作为网络库,在公共代码部分会使用 BuildConfig.BASE_URL 作为网络库地址。可以看到 BASE_URL 这个变量的名字,与我们上面在 gradle 中定义的变量是一样的。其实这个 BuildConfig 类就是由 gradle 编译时生成的类,它的内容大概是:

    /**
     * Automatically generated file. DO NOT MODIFY
     */
    package com.example.xue.myapplication;
    
    public final class BuildConfig {
      public static final boolean DEBUG = Boolean.parseBoolean("true");
      public static final String APPLICATION_ID = "com.example.xue.myapplication";
      public static final String BUILD_TYPE = "debug";
      public static final String FLAVOR = "dev";
      public static final int VERSION_CODE = 1;
      public static final String VERSION_NAME = "1.0";
      // Fields from product flavor: dev
      public static final String BASE_URL = "http://192.168.20.100/flavors/";
    }
    

    可以看到这个类的最后一行和它的注释这个就是我们配置的变量,这就说明了,刚才为什么要用单引号嵌套双引号。因为它是个String类型的变量,如果是 int 或者 boolean 类型就不需要写双引号了。

    默认是 dev 地址的包,如果开发过程中想要使用 ftest 的包怎么办(ps:ftest不是打错了,是不让用test作为开头,所以可以使用for test -> test 或者 te5t 之类的作为名字)?可以使用 Build Variants 来切换环境包。

    Build Variants

    切换后 BuildConfig 会重新生成,也就能使用相应的地址了,这也就是切换地址的原理。打包时就更方便了:

    打包页面效果

    可以选择需要的地址甚至是运行release包,来测试应用。这个方式可以还可以替换应用ID、应用名、应用图标等,计划在另外的教程内讲解。

    双维度

    如果公司要求不止三个地址,还需要区分手机和平板的应用,这时应该怎么办,难道是写六个配置吗?no,只需要写五个(ps:好像没有节省太多吖。。。)

    先上配置:

    // 维度定义
    flavorDimensions "path", "type"
    
    productFlavors {
        dev {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
        }
    
        ftest {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
        }
    
        pro {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
        }
    
        mobile {
            dimension "type"
            applicationId "com.conan.multiflavors.mobile"
        }
    
        hd {
            dimension "type"
            applicationId "com.conan.multiflavors.hd"
        }
    }
    

    可以看到 flavorDimensions 有了变化,上面我们没有讲,如果只有一个默认的值,基本可以忽略它的存在。这个单词的翻译,我没有找到确切的答案,有人称之为维度,我自己叫它调味盘。一份料理可以分成多个工序,手法,调料,食材,烹饪时间,改变一样料理就会有不同的味道,它们之间的组合就是笛卡尔积的关系。而 flavorDimensions 就是用来有多少个维度的。

    然后每个配置会发现都多了一个 dimension ,这是用来指定当前配置属于哪个维度,这样 gradle 就会为我们生成多个维度的组合关系。

    多维度

    可以看到这里生成之前两倍的类型,值都是笛卡尔积的关系。打包的位置也是同理的,为了偷懒就不放图了。

    三维度

    这时如果需求找你,我们需要定义友盟渠道包,用来统计不用应用市场的运营情况。友盟需要在注册位置传入不用的渠道名作为区分,聪明的你应该想到了,这里还需要定义一个维度。

    // 维度定义
    flavorDimensions "path", "type", "channel"
    
    productFlavors {
        dev {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
        }
    
        ftest {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
        }
    
        pro {
            dimension "path"
            buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
        }
    
        mobile {
            dimension "type"
            applicationId "com.conan.multiflavors.mobile"
        }
    
        hd {
            dimension "type"
            applicationId "com.conan.multiflavors.hd"
        }
    
        xiaomi {
            dimension "channel"
            manifestPlaceholders = [channel: "xiaomi"]
        }
    
        huawei {
            dimension "channel"
            manifestPlaceholders = [channel: "huawei"]
        }
    
        smartision {
            dimension "channel"
            manifestPlaceholders = [channel: "smartision"]
        }
    }
    

    新增了一个 channel 的维度,用来区分不用的渠道商的类别,这里定义了三种,真实的可能需要十几种吧。

    口算一下我们这次定义了 3 + 2 + 3 = 8 个配置,如果全都写在一起 3 * 2 * 3 = 18 个配置,可以节省很多配置呦。

    打包时就可以选择相应渠道包,可以单选可以多选,一次性打出所有的包。这里要夸下 google,以前在这列出了所有的 release 和 debug 很不方便,现在有了改进,将 release 和 debug 改进成了下拉框,也是本来打包功能大部分需求也是 release 很少需要 debug 包的。

    一次性打包

    给大家看个产物,基本跟正常打包时差不多,也就是花打一个包的时间打出了所有需要的包。

    产物

    因为不同的渠道产生的文件夹不一样,所以对 git 的 ignore 文件有影响,我是这样配置的忽略规则。

    release
    debug
    

    by 费城的二鹏 2020.5.2 白山

    相关文章

      网友评论

          本文标题:Android多渠道打包--多维度

          本文链接:https://www.haomeiwen.com/subject/kuxkghtx.html