您的位置:

深入浅出:androidsourcesets全解析

一、什么是androidsourcesets

androidsourcesets是Android Studio项目中的一个非常重要的概念。它可以让我们在同一个项目中构建多个版本和变体,每个版本和变体可以有自己的代码、资源和配置文件。简单的说,就是我们可以通过androidsourcesets在一个项目中构建出多个独立的apk。

在一个Android Studio项目中,通常会包含两个androidsourcesets:main和androidTest。其中main是主要的源码集,所有版本和变体共享这个源码集。而androidTest则是测试代码的源码集,只有单元测试和Android Instrumentation测试可以使用它。

二、如何使用androidsourcesets

首先,我们需要在build.gradle文件中定义androidsourcesets:

android {
    ...
    sourceSets {
        free {
            manifest.srcFile 'src/free/AndroidManifest.xml'
            java.srcDirs = ['src/free/java']
            res.srcDirs = ['src/free/res']
        }
        paid {
            manifest.srcFile 'src/paid/AndroidManifest.xml'
            java.srcDirs = ['src/paid/java']
            res.srcDirs = ['src/paid/res']
        }
    }
}

上面的代码定义了两个androidsourcesets:free和paid。每个androidsourcesets都指定了对应的AndroidManifest.xml、Java源码和资源文件所在目录。

接下来,我们可以在同一个项目中构建出多个版本和变体。例如,在创建buildType的时候指定使用的androidsourcesets:

android {
    ...
    buildTypes {
        debug {
            ...
        }
        release {
            ...
        }
        customType {
            ...
            resConfigs "en", "fr"
            initWith debug
            applicationIdSuffix ".customType"
            sourceSets {
                free {
                    manifest.srcFile 'src/customTypeFree/AndroidManifest.xml'
                    java.srcDirs = ['src/customTypeFree/java']
                    res.srcDirs = ['src/customTypeFree/res']
                }
                paid {
                    manifest.srcFile 'src/customTypePaid/AndroidManifest.xml'
                    java.srcDirs = ['src/customTypePaid/java']
                    res.srcDirs = ['src/customTypePaid/res']
                }
            }
        }
    }
}

上面的代码创建了一个名为customType的buildType。为了使用自定义的androidsourcesets,我们需要在customType里重新定义它们。注意,在customType里我们可以定义不同的资源配置(使用resConfigs)或者应用ID后缀(使用applicationIdSuffix),以便在构建不同的版本和变体时能够正确的识别它们。

三、androidsourcesets常用场景

1、分渠道打包

在实际开发中,我们经常需要将同一个应用打包成不同的渠道,以便于在市场上进行多渠道推广。使用androidsourcesets,我们可以很方便的实现这一功能。例如,在build.gradle文件中定义渠道相关的androidsourcesets:

android {
    ...
    productFlavors {
        xiaomi {
            ...
            sourceSets {
                free {
                    manifest.srcFile 'src/xiaomiFree/AndroidManifest.xml'
                    java.srcDirs = ['src/xiaomiFree/java']
                    res.srcDirs = ['src/xiaomiFree/res']
                }
                paid {
                    manifest.srcFile 'src/xiaomiPaid/AndroidManifest.xml'
                    java.srcDirs = ['src/xiaomiPaid/java']
                    res.srcDirs = ['src/xiaomiPaid/res']
                }
            }
        }
        oppo {
            ...
            sourceSets {
                free {
                    manifest.srcFile 'src/oppoFree/AndroidManifest.xml'
                    java.srcDirs = ['src/oppoFree/java']
                    res.srcDirs = ['src/oppoFree/res']
                }
                paid {
                    manifest.srcFile 'src/oppoPaid/AndroidManifest.xml'
                    java.srcDirs = ['src/oppoPaid/java']
                    res.srcDirs = ['src/oppoPaid/res']
                }
            }
        }
    }
}

上面的代码定义了两个productFlavors:xiaomi和oppo。每个flavor都定义了对应的androidsourcesets。当使用不同的flavor构建apk时,系统会根据不同的sourceSets打包出不同的apk。

2、分模块开发

在较大的应用中,为了方便开发和维护,我们可以将应用分成多个模块进行开发。使用androidsourcesets,我们可以在一个项目中构建多个独立的模块和apk。例如,在build.gradle文件中定义不同的androidsourcesets:

android {
    ...
    sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
            java.srcDirs = ['src/main/java']
            res.srcDirs = ['src/main/res']
        }
        module1 {
            manifest.srcFile 'src/module1/AndroidManifest.xml'
            java.srcDirs = ['src/module1/java']
            res.srcDirs = ['src/module1/res']
        }
        module2 {
            manifest.srcFile 'src/module2/AndroidManifest.xml'
            java.srcDirs = ['src/module2/java']
            res.srcDirs = ['src/module2/res']
        }
    }
}

上面的代码定义了三个androidsourcesets:main、module1和module2。每个androidsourcesets都定义了对应的AndroidManifest.xml、Java源码和资源文件所在目录。接下来,我们可以在同一个项目中构建出多个独立的apk。

3、多语言版本开发

在国际化应用中,为了提供更好的用户体验,我们需要提供多语言版本的应用。使用androidsourcesets,我们可以很方便的实现这一功能。例如,在build.gradle文件中定义不同语言版本的androidsourcesets:

android {
    ...
    productFlavors {
        english {
            ...
            sourceSets {
                free {
                    manifest.srcFile 'src/englishFree/AndroidManifest.xml'
                    java.srcDirs = ['src/englishFree/java']
                    res.srcDirs = ['src/englishFree/res']
                }
                paid {
                    manifest.srcFile 'src/englishPaid/AndroidManifest.xml'
                    java.srcDirs = ['src/englishPaid/java']
                    res.srcDirs = ['src/englishPaid/res']
                }
            }
        }
        french {
            ...
            sourceSets {
                free {
                    manifest.srcFile 'src/frenchFree/AndroidManifest.xml'
                    java.srcDirs = ['src/frenchFree/java']
                    res.srcDirs = ['src/frenchFree/res']
                }
                paid {
                    manifest.srcFile 'src/frenchPaid/AndroidManifest.xml'
                    java.srcDirs = ['src/frenchPaid/java']
                    res.srcDirs = ['src/frenchPaid/res']
                }
            }
        }
    }
}

上面的代码定义了两个语言版本的productFlavors:english和french。每个flavor都定义了对应的androidsourcesets。使用resConfigs属性,我们可以指定打包时仅使用特定语言的资源。

四、总结

androidsourcesets是Android Studio项目中非常重要的概念,可以让我们在同一个项目中构建多个版本和变体。androidsourcesets常用于分渠道打包、分模块开发和多语言版本开发等场景,对于大型项目非常实用。