android之gradle版本差异化打包

对于版本差异化打包,如果实际工作中没怎么用到,对这块一般不会很熟悉,记得在上一家公司的时候,一个主版本公司自己用的,由于公司和其他的公司有合作,其他公司对于app要求定制化,总体上的功能没怎么变化,主要的变化还是界面(背景,图片还有一些文字之类的),一开始采用的方案是基于主版本新建一个工程,刚开始还没什么,但到后面发现问题越来越多了,很不利于维护,工程多了管理起来也很麻烦,不过最开始也是在eclipse上开发,后面接触到android studio,发现android studio很好的解决了版本差异化打包这个问题,效率提高的不止一点点,比如,之前如果发现bug,在每个版本上都需要修改,但迁移到android studio上后,配置好差异化打包后,只需更改一个就可以了。接下来就一起来探讨下。

如何实现自己自己的差异化打包,这里先来了解个需求,有需求才好下手不是。假如一开始有个主版本master,由于后期公司的发展,与xiaomi、huawei、meizhu等有合作了,公司开始要求基于主版本开发与xiaomi、huawei、meizhu的定制化版本,随意业务的发展,xiaomi可能要求在不同的渠道要有不同的定制化,既然有这样的需求,那肯定就是干呗,需求有了,接下来就是分析该如何下手了,思路有以下三种:

1、每一个定制版本都新建一个工程;

2、每一个定制版本都从主版本上拉一个分支出来;

3、一个工程,通过gradle实现差异化配置;

对于1、2点的方案肯定是不可取,后期的维护成本过大,所以这里采取的3方案,这里要说的也是第三个方案,配置起来很简单,如下配置即可:

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.zzq.variantdemo"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    flavorDimensions 'company','chanel'
    productFlavors {
        master {
            dimension 'company'
        }
        meizhu {
            dimension 'company'
        }
        huawei {
            dimension 'company'
        }
        xiaomi {
            dimension 'company'
        }
        chanelA {
            dimension 'chanel'
        }
        chanelB {
            dimension 'chanel'
        }
    }
}

看flavorDimensions和productFlavors这两个配置,flavorDimensions配置的是维度,productFlavors通过维度再进行细化的配置,这里以master(主版本)为例,通过productFlavors这样配置后,这里master的差异化版本就有masterchannelA和masterchanelB两个差异化版本,在加上debug和release,所以master的差异化版本就达到4个,以此类推xiaomi、huawei、meizhu,这样配置后总的差异化版本就达到16个,这里只是配置了,但每个版本的差异化还没有实现,这个实现主要涉及到两个方面,一是资源文件,二是代码的逻辑。

在上面这样配置完成后,接下来做的就是去src包下面新建文件夹了,如下图:

就是将productFlavors下面配置公司名和渠道名都在src包下新建一个文件夹,然后参照main包下的格式添加java代码、资源文件或是AndroidMenifest,这里添加的就是与主版本有差异化的东西,因为当这里的资源文件与main包下的资源文件有冲突时,这里添加的资源文件就会替换掉main包下的资源文件,但对于java包下的类文件则不然,当main包下有的类文件,其他包下就一定是不能有的,说到这可能还不太明白,接下来举个具体的例子:

如果想打对应的差异化包,如下图进行选择:

所谓差异化打包就是将不同包下面的文件进行整合,以打的包是masterChanelADebug为例说下这样配置是如何实现差异化的,下面将分为三个方面来说:

1、java包下的类文件(这里所指的是包名和类名全部相同)整合,如果master包下有People.class文件,那么在chanelA包下和main包下就不能有,在master包下没有People.class没有,在chanelA包下有,那么在main包下就不能有,以此类推;

2、res包下的资源文件整合,分为两种:一是资源文件没有冲突,那么就以添加的方式进行合并,二是如果有冲突,那么合并的时候就遵循以下优先级:master>chanelA>main

3、AndroidMenifest文件中配置同样会整合到一起,同样分为两种,一是没有冲突那就直接合并,二是如果有冲突,默认的合并规则是报异常,所以这时就需要指定合并规则了,如何指定指定合并规则不是这里的重点, 有冲突时根据提示的异常添加即可,这里看个简单的替换规则:

AndroidMenifest.xml文件下都有custom_name,这时如果不指定规则,编译肯定是会有异常的,在master下的AndroidMenifest.xml添加了如下规则:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.zzq.variantdemo">

    <application>
        <meta-data android:name="custom_name"
            android:value="chanel"
            tools:replace="android:value"/>
    </application>

</manifest>

可以分为两步:

1、引入:xmlns:tools="http://schemas.android.com/tools"

2、指定规则:tools:replace="android:value",大多数情况这个就够用了,如果还有其他需求,也可以添加其他规则,感兴趣的可以自行百度。

这里添加规则也是有优先级的,需在优先级高的添加规则:master>chanelA>main

 

 

猜你喜欢

转载自blog.csdn.net/tangedegushi/article/details/82857875