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

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

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

为了能够让项目多人并行快速高质量开发,在开发前期我们可以做很多事情来较少后期重复的工作量,本次梳理一下一个项目的配置信息如何统一管理。一个项目中包含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"
    }
    原文作者:AnonyPer
    原文地址: https://www.jianshu.com/p/b7f1e1aa7485
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞