Android项目框架思考--配置文件

作者: AnonyPer | 来源:发表于2018-11-26 17:26 被阅读5次

    很早就想写一些相关的技术文档,一来锻炼自己的书写能力,二来也能记录自己的成长痕迹。每过一段时间写一篇技术文章,希望自己能够一直坚持下去。

    一个合适的框架能够让项目开发顺畅,代码条理清晰、功能实现效率提升,以及运行时减少很多人为水平原因的错误。

    为了能够让项目多人并行快速高质量开发,在开发前期我们可以做很多事情来较少后期重复的工作量,本次梳理一下一个项目的配置信息如何统一管理。一个项目中包含application以及其他作为lib库的module,他们的build.gradle都有一些配置信息,将配置信息统一化,一方面便于后期快速更改项目的编译环境,另一方方面也能快速的使他人接入开发,不会因为电脑环境变量的改变而花费很多时间来回修改mudle的配置参数。

    我们通过AndroidStudio创建一个默认的项目时,其配置文件大题如下:

    application中的build.gradle

        apply plugin: 'com.android.application'
        
        android {
            compileSdkVersion 26
            defaultConfig {
                applicationId "com.kotlin.anonyper.testapplication"
                minSdkVersion 15
                targetSdkVersion 26
                versionCode 1
                versionName "1.0"
                testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            }
            buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
            }
            compileOptions {
                targetCompatibility 1.8
                sourceCompatibility 1.8
            }
        }
        
        dependencies {
            implementation fileTree(dir: 'libs', include: ['*.jar'])
            implementation 'com.android.support:appcompat-v7:26.1.0'
            implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        }
        
    

    module中的build.gradle

        apply plugin: 'com.android.library'
        
        android {
            compileSdkVersion 26
            defaultConfig {
                minSdkVersion 15
                targetSdkVersion 26
                versionCode 1
                versionName "1.0"
                testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            }
        
            buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
            }
        
        }
        dependencies {
            implementation fileTree(dir: 'libs', include: ['*.jar'])
        
            implementation 'com.android.support:appcompat-v7:26.1.0'
            testImplementation 'junit:junit:4.12'
            androidTestImplementation 'com.android.support.test:runner:1.0.2'
            androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        }
    

    可以看到上面,每一个build.gradle中都有compileSdkVersion、defaultConfig等信息(在module中有一些参数是非必要),加上我们直接从网络上下载的第三方module他们的配置参数很大可能和上面的不一样,这样就导致同一个项目在不同的电脑上都需要一个一个的module去调整配置信息,而这个过程对于新手来说稍不留神就是非常痛苦的。所以我们可以将这些共同的参数提取出来,写到同一个地方。

    项目的根目录下有一个叫做gradle.properties的文件,我们可以在这里写一些项目所需要的公共参数,以便于不同的module来使用:

    gradle.properties样例

    # Project-wide Gradle settings.
    # IDE (e.g. Android Studio) users:
    # Gradle settings configured through the IDE *will override*
    # any settings specified in this file.
    # For more details on how to configure your build environment visit
    # http://www.gradle.org/docs/current/userguide/build_environment.html
    # Specifies the JVM arguments used for the daemon process.
    # The setting is particularly useful for tweaking memory settings.
    # Default value: -Xmx10248m -XX:MaxPermSize=256m
    # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
    # When configured, Gradle will run in incubating parallel mode.
    # This option should only be used with decoupled projects. More details, visit
    # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
    # org.gradle.parallel=true
    ###################################################
    #############  gradle 优化(确实快了不少) #############
    ###################################################
    # Project-wide Gradle settings.
    # IDE (e.g. Android Studio) users:
    # Settings specified in this file will override any Gradle settings
    # configured through the IDE.
    # For more details on how to configure your build environment visit
    # http://www.gradle.org/docs/current/userguide/build_environment.html
    # The Gradle daemon aims to improve the startup and execution time of Gdradle.
    # When set to true the Gradle daemon is to run the build.
    # TODO: disable daemon on CI, since builds should be clean and reliable on servers
    org.gradle.daemon=true
    # Specifies the JVM arguments used for the daemon process.
    # The setting is particularly useful for tweaking memory settings.
    # Default value: -Xmx10248m -XX:MaxPermSize=256m
    org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
    # When configured, Gradle will run in incubating parallel mode.
    # This option should only be used with decoupled projects. More details, visit
    # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
    org.gradle.parallel=true
    # Enables new incubating mode that makes Gradle selective when configuring projects.
    # Only relevant projects are configured which results in faster builds for large multi-projects.
    # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
    org.gradle.configureondemand=true
    # 版本编译配置
    ANDROID_BUILD_MIN_SDK_VERSION=15
    ANDROID_BUILD_TARGET_SDK_VERSION=26
    ANDROID_BUILD_SDK_VERSION=26
    ANDROID_BUILD_TOOLS_VERSION=26.0.0
    # 版本号、包名等配置
    APPLICATION_ID=com.kotlin.anonyper.testapplication
    ANDROID_BUILD_VER_CODE=1
    ANDROID_BUILD_VER_NAME=1.0
    # 签名证书配置
    STORE_FILE=/Users/Documents/tianqismart/xxx.jks
    STORE_PASSWORD=xxx1234
    KEY_ALIAS=xxxx
    KEY_PASSWORD=xxx1234
    #平台参数配置
    GAODE_APPKEY=b5743c922cb683eff0d090272b4aa571
    JPUSH_APPKEY=1d732d903966481323ca4c7f
    # 解决RN64位兼容
    android.useDeprecatedNdk=true
    #java版本
    JAVA_VERSION=1.8
    #gradle版本
    GRADLE_VERSION=3.0.1
    
    

    在appliciton的build.gradle中使用

       apply plugin: 'com.android.application'
        
        //key为 gradle.properties里定义的变量
        //编译的sdk版本
        def ANDROID_BUILD_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_SDK_VERSION")
        if (ANDROID_BUILD_SDK_VERSION == null) {
            ANDROID_BUILD_SDK_VERSION = "26" //给出默认值
        }
        //app min sdk version
        def ANDROID_BUILD_MIN_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_MIN_SDK_VERSION")
        if (ANDROID_BUILD_MIN_SDK_VERSION == null) {
            ANDROID_BUILD_MIN_SDK_VERSION = "15" //给出默认值
        }
        //app target sdk version
        def ANDROID_BUILD_TARGET_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_TARGET_SDK_VERSION")
        if (ANDROID_BUILD_TARGET_SDK_VERSION == null) {
            ANDROID_BUILD_TARGET_SDK_VERSION = "1" //给出默认值
        }
        //app version code
        def ANDROID_BUILD_VER_CODE = project.getProperties().get("ANDROID_BUILD_VER_CODE")
        if (ANDROID_BUILD_VER_CODE == null) {
            ANDROID_BUILD_VER_CODE = "1" //给出默认值
        }
        //app version name
        def ANDROID_BUILD_VER_NAME = project.getProperties().get("ANDROID_BUILD_VER_NAME")
        if (ANDROID_BUILD_VER_NAME == null) {
            ANDROID_BUILD_VER_NAME = "1.0" //给出默认值
        }
        //编译的tools版本
        def ANDROID_BUILD_TOOLS_VERSION = project.getProperties().get("ANDROID_BUILD_TOOLS_VERSION")
        if (ANDROID_BUILD_TOOLS_VERSION == null) {
            ANDROID_BUILD_TOOLS_VERSION = "26.0.0" //给出默认值
        }
        //app的包名
        def ANDROID_APPLICATION_ID = project.getProperties().get("APPLICATION_ID")
        if (ANDROID_APPLICATION_ID == null) {
            ANDROID_APPLICATION_ID = "com.kotlin.anonyper.testapplication" //给出默认值
        }
        //高德key
        def GAODE_APPKEY = project.getProperties().get("GAODE_APPKEY")
        //极光key
        def JPUSH_APPKEY = project.getProperties().get("JPUSH_APPKEY")
        //签名文件地址
        def STORE_FILE = project.getProperties().get("STORE_FILE")
        if (STORE_FILE == null) {
            STORE_FILE = "/Users/Documents/tianqismart/xxx.jks" //给出默认值
        }
        //签名文件的密码
        def STORE_PASSWORD = project.getProperties().get("STORE_PASSWORD")
        if (STORE_PASSWORD == null) {
            STORE_PASSWORD = "xxxx1234" //给出默认值
        }
        //签名文件别名
        def KEY_ALIAS = project.getProperties().get("KEY_ALIAS")
        if (KEY_ALIAS == null) {
            STORE_PASSWORD = "xxxx" //给出默认值
        }
        //编译文件别名对应的密码
        def KEY_PASSWORD = project.getProperties().get("KEY_PASSWORD")
        if (KEY_PASSWORD == null) {
            KEY_PASSWORD = "xxxx1234" //给出默认值
        }
        
        android {
            compileSdkVersion Integer.parseInt(ANDROID_BUILD_SDK_VERSION as String)
        
        
            defaultConfig {
                applicationId ANDROID_APPLICATION_ID
                minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION as String)
                targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION as String)
                versionCode Integer.parseInt(ANDROID_BUILD_VER_CODE as String)
                versionName ANDROID_BUILD_VER_NAME
                manifestPlaceholders = [
                        GAODE_APPKEY : GAODE_APPKEY,
                        JPUSH_PKGNAME: ANDROID_APPLICATION_ID,
                        JPUSH_APPKEY : JPUSH_APPKEY, //JPush上注册的包名对应的appkey.
                ]
        
            }
            signingConfigs {
                release {
                    //签名
                    storeFile file(STORE_FILE)
                    storePassword STORE_PASSWORD
                    keyAlias KEY_ALIAS
                    keyPassword KEY_PASSWORD
                }
            }
        
        
            buildTypes {
                debug {
                    buildConfigField "boolean", "LOG_DEBUG", "true"
                    shrinkResources false
                    signingConfig signingConfigs.release
                    minifyEnabled false
                }
                release {
                    // 不显示Log
                    buildConfigField "boolean", "LOG_DEBUG", "false"
                    //是否混淆
                    minifyEnabled true
                    // 移除无用的resource文件
                    shrinkResources false
                    //
                    debuggable false
                    jniDebuggable false
                    zipAlignEnabled true
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                    signingConfig signingConfigs.release
                }
            }
         
            ompileOptions {
                sourceCompatibility JAVA_VERSION
                targetCompatibility JAVA_VERSION
            }
        
        }
        
        
        allprojects {
            repositories {
                maven { url "https://maven.google.com" }
                jcenter()
                mavenCentral()
        
                flatDir {
                    dirs 'libs'
                }
            }
        }
        
        dependencies {
            implementation fileTree(dir: 'libs', include: ['*.jar'])
            implementation 'com.android.support:appcompat-v7:26.1.0'
            implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        }
        
    

    里面的默认值可以给,可以不写。不写的话就必须在gradle.properties文件中配置了用到的参数。

    module中的build.gradle

        apply plugin: 'com.android.library'
        
        def ANDROID_BUILD_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_SDK_VERSION")
        if (ANDROID_BUILD_SDK_VERSION == null) {
            ANDROID_BUILD_SDK_VERSION = "26" //给出默认值
        }
        //app min sdk version
        def ANDROID_BUILD_MIN_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_MIN_SDK_VERSION")
        if (ANDROID_BUILD_MIN_SDK_VERSION == null) {
            ANDROID_BUILD_MIN_SDK_VERSION = "15" //给出默认值
        }
        //app target sdk version
        def ANDROID_BUILD_TARGET_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_TARGET_SDK_VERSION")
        if (ANDROID_BUILD_TARGET_SDK_VERSION == null) {
            ANDROID_BUILD_TARGET_SDK_VERSION = "1" //给出默认值
        }
        //app version code
        def ANDROID_BUILD_VER_CODE = project.getProperties().get("ANDROID_BUILD_VER_CODE")
        if (ANDROID_BUILD_VER_CODE == null) {
            ANDROID_BUILD_VER_CODE = "1" //给出默认值
        }
        //app version name
        def ANDROID_BUILD_VER_NAME = project.getProperties().get("ANDROID_BUILD_VER_NAME")
        if (ANDROID_BUILD_VER_NAME == null) {
            ANDROID_BUILD_VER_NAME = "1.0.0" //给出默认值
        }
        //编译的tools版本
        def ANDROID_BUILD_TOOLS_VERSION = project.getProperties().get("ANDROID_BUILD_TOOLS_VERSION")
        if (ANDROID_BUILD_TOOLS_VERSION == null) {
            ANDROID_BUILD_TOOLS_VERSION = "26.0.0" //给出默认值
        }
        android {
        
            compileSdkVersion Integer.parseInt(ANDROID_BUILD_SDK_VERSION as String)
            defaultConfig {
                minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION as String)
                targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION as String)
                versionCode Integer.parseInt(ANDROID_BUILD_VER_CODE as String)
                versionName ANDROID_BUILD_VER_NAME
            }
        
            buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
            }
        
        }
        
        dependencies {
            implementation fileTree(dir: 'libs', include: ['*.jar'])
            implementation 'com.android.support:appcompat-v7:26.1.0'
            testImplementation 'junit:junit:4.12'
            androidTestImplementation 'com.android.support.test:runner:1.0.2'
            androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        }
        
    

    多个module时候配置同上。这样我们就将相关的参数都统一到一个文件中,以后切换、修改参数也只需要修改一个地方其他地方都会同步过来。

    以上只是简单的抽离了配置的参数,其实引入的第三方lib的版本也可以统一在一个地方配置,同时除了将配置信息统一写到gradle.properties中之外,也可以将参数写在项目根目录的build.gradle中,如下:

        // Top-level build file where you can add configuration options common to all sub-projects/modules.
        def GRADLE_VERSION = project.getProperties().get("GRADLE_VERSION")
        buildscript {
        
            repositories {
                google()
                jcenter()
            }
            dependencies {
                classpath "com.android.tools.build:gradle:${GRADLE_VERSION}"
            }
        }
        
        allprojects {
            repositories {
                google()
                jcenter()
            }
        }
        
        task clean(type: Delete) {
            delete rootProject.buildDir
        }
        ext {
            // Sdk and tools
            compileSdkVersion = 26
            supportLibraryVersion = '26.1.0'
            constraintLayoutVersion = '1.1.3'
            //其他参数
        }
        
    

    上面的ext里面就是参数的配置,具体使用方法:

        compileSdkVersion Integer.parseInt("$rootProject.ext.compileSdkVersion" as String)
        或者:
        dependencies {
            implementation fileTree(dir: 'libs', include: ['*.jar'])
            implementation "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
        }
    

    相关文章

      网友评论

        本文标题:Android项目框架思考--配置文件

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