Android项目中的properties大阅兵

作者: 苌蓊芪 | 来源:发表于2018-08-15 13:41 被阅读6次

    背景

    最近在封装一个分享功能库,因为没有自己的腾讯\微信\微博开放平台账号,所以使用了公司项目的api_key和keystore,于是带来了一个问题,这些信息是绝对不能提交到github上去的,所以每次提交代码时,都需要把相关的代码删除。某次,提交代码时忘了这一步操作,误将这些敏感的信息push到了github上,急忙使用git命令来挽救这次失误:

    git reset --hard <commit_id>
    git push origin HEAD --force
    

    在挽救回这次操作之后,我开始反思、寻找更好的解决方法,最终目标是让 代码脱敏 ,即无论怎么迭代代码,push时都不用再担心会把敏感信息误提交了

    配置文件

    首先,我们先来回顾一下Android Studio里的Project板块,当展示模式切换成Android之后,我们会看到有一个Gradle Scripts的集合,今天的主角都在这里面,让我们暂时先忘记日常写代码的module,把全部的注意力放在Gradle Scripts部分。


    gradle_scripts.jpeg

    在图中,我们可以看到gradle.properties(Global Properties)、gradle.prooperties(Project Properties)、local.properties(SDK Location)等三个配置文件,而它们就是我们的武器。

    gradle.properties(Global Properties)

    从文件名后的注释我们可以知道,它是Gradle全局性的配置文件,在Linux、Mac中,它位于/Users/{YOUR_NAME}/.gradle/,windows用户请自行google确定它的位置。也有部分用户可能会没有这个文件,此时应该自己创建一个,它会在我们日常工作中提供非常大的帮助。

    global_properties.jpeg

    打开这个文件,我们可以看到,里面默认配置了gradle的JVM最大可用内存、持久代可用大小、以及一些gradle的优化参数,这些配置是所有项目共享的。

    跟随这一思路,当我们有某些配置是所有项目都会用到的,那么就可以把它配置在这个文件中,这样就不必每次新建、clone一个项目之后,还要去一一配置。比如bintray、nexus的账号信息。

    由于这个文件并不在项目下,所以我们可以大胆的把敏感信息配置在里面,而不用担心会push到git上。

    gradle.properties(Project Properties)

    顾名思义,这个文件是项目级的配置文件,由于它会被提交到git上,所以不适合配置敏感信息,此处就不多做介绍。一般这个配置文件中会配置项目级的功能开关,比如android.useAndroidX、android.enableJetifier等。

    在现在比较流行的组件化开发中,module是application还是library的开关通常也会配置在这里。

    local.properties(SDK Location)

    这个文件中默认配置了本地的sdk、ndk路径。该文件的header中写到:

    This file must NOT be checked into Version Control Systems

    然而,这个文件很多时候并不会被VCS忽略,所以需要手动将它排除。因此,在把敏感信息配置在这个文件中时,我们要确保它没有被VCS收录。

    系统环境变量

    除了上述3种配置文件之外,某些情况下,我们还可以使用系统环境变量来配置敏感信息。但是由于它是系统级的,某些情况下可能会无法正常读取,甚至极端情况下会因为配置错误,导致系统宕机。所以,除非不得不配置在系统环境变量中,否则建议不要配置成系统环境变量。

    读取上述配置文件

    在上一部分,我们了解了在一个 Android 项目中可以使用到的配置文件类型,现在来看一下,当配置完成之后,我们怎么读取使用这些配置。

    gradle.properties(Global AND Project)

    1. 在任意.gradle文件中,我们可以通过getProperties().get("KEY_NAME")方式来读取参数值
    
    def getRepositoryUsername() {
        return getProperties().get('bintray.user')
    }
    
    def getRepositoryPassphrase() {
        return getProperties().get('bintray.gpg.password')
    }
    
    def getApiKey() {
        return getProperties().get("bintray.apikey")
    }
    
    
    1. 在Android项目的build.gradle中,可以直接用KEY来获取参数值
    signingConfigs {
            sign {
                storeFile file(ANDROID_STORE_FILE)
                storePassword ANDROID_STORE_PASSWORD
                keyAlias ANDROID_KEY_ALIAS
                keyPassword ANDROID_KEY_PASSWORD
            }
        }
    

    local.properties

    由于这个配置文件只供gradle程序使用,所以无法像gradle.properties那样直接读取。我们需要通过JDK的Properties类去手动加载它,然后读取其中的参数

     Properties properties = new Properties()
        properties.load project.rootProject.file('local.properties').newDataInputStream()
        def APP_ID = properties.getProperty("APP_ID")
        def WB_ID = properties.getProperty("WB_ID")
        def WX_ID = properties.getProperty("WX_ID")
        def QQ_ID = properties.getProperty("QQ_ID")
    

    系统环境变量

    虽然不建议这种配置方式,但是还是简单地介绍下读取方法,由于它是系统级参数,所以在gradle文件中,我们可以通过System.getenv来读取

    def env = { System.getenv it }
    signingConfigs {
        sign {
          storeFile file(env("ANDROID_STORE_FILE"))
          storePassword env("ANDROID_STORE_PASSWORD")
          keyAlias env("ANDROID_KEY_ALIAS")
          keyPassword env("ANDROID_KEY_PASSWORD")
        }
      }
    

    最佳实践

    在上文中介绍了不同的配置文件以及它的读取方法。最后,我想介绍一下在这次封装分享库时的一些最佳实践

    1. 不同项目间通用的配置建议放在Global Properties中,如Bintray、Nexus账号信息
    2. 项目专有的敏感信息,如微信\腾讯\微博开放平台的KEY建议放在local.properties中
    3. Project Properties中只存放不敏感的参数
    4. 除非必须,否则不要使用系统环境变量

    末尾

    安利一下使用kotlin语言封装的分享库RxShare,使用RxJava实现一行代码完成分享。

    相关文章

      网友评论

        本文标题:Android项目中的properties大阅兵

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