背景
最近在封裝一個分享功能庫,因?yàn)闆]有自己的騰訊\微信\微博開放平臺賬號用押,所以使用了公司項(xiàng)目的api_key和keystore尊勿,于是帶來了一個問題,這些信息是絕對不能提交到github上去的豆巨,所以每次提交代碼時剩辟,都需要把相關(guān)的代碼刪除。某次往扔,提交代碼時忘了這一步操作贩猎,誤將這些敏感的信息push到了github上,急忙使用git命令來挽救這次失誤:
git reset --hard <commit_id>
git push origin HEAD --force
在挽救回這次操作之后萍膛,我開始反思吭服、尋找更好的解決方法,最終目標(biāo)是讓 代碼脫敏 蝗罗,即無論怎么迭代代碼艇棕,push時都不用再擔(dān)心會把敏感信息誤提交了。
配置文件
首先串塑,我們先來回顧一下Android Studio里的Project板塊沼琉,當(dāng)展示模式切換成Android之后,我們會看到有一個Gradle Scripts的集合拟赊,今天的主角都在這里面刺桃,讓我們暫時先忘記日常寫代碼的module,把全部的注意力放在Gradle Scripts部分吸祟。
在圖中瑟慈,我們可以看到gradle.properties(Global Properties)桃移、gradle.prooperties(Project Properties)、local.properties(SDK Location)等三個配置文件葛碧,而它們就是我們的武器借杰。
gradle.properties(Global Properties)
從文件名后的注釋我們可以知道,它是Gradle全局性的配置文件进泼,在Linux蔗衡、Mac中,它位于/Users/{YOUR_NAME}/.gradle/乳绕,windows用戶請自行g(shù)oogle確定它的位置绞惦。也有部分用戶可能會沒有這個文件,此時應(yīng)該自己創(chuàng)建一個洋措,它會在我們?nèi)粘9ぷ髦刑峁┓浅4蟮膸椭?/p>
打開這個文件济蝉,我們可以看到,里面默認(rèn)配置了gradle的JVM最大可用內(nèi)存菠发、持久代可用大小王滤、以及一些gradle的優(yōu)化參數(shù),這些配置是所有項(xiàng)目共享的滓鸠。
跟隨這一思路雁乡,當(dāng)我們有某些配置是所有項(xiàng)目都會用到的,那么就可以把它配置在這個文件中糜俗,這樣就不必每次新建踱稍、clone一個項(xiàng)目之后,還要去一一配置吩跋。比如bintray寞射、nexus的賬號信息。
由于這個文件并不在項(xiàng)目下锌钮,所以我們可以大膽的把敏感信息配置在里面,而不用擔(dān)心會push到git上引矩。
gradle.properties(Project Properties)
顧名思義梁丘,這個文件是項(xiàng)目級的配置文件,由于它會被提交到git上旺韭,所以不適合配置敏感信息氛谜,此處就不多做介紹。一般這個配置文件中會配置項(xiàng)目級的功能開關(guān)区端,比如android.useAndroidX值漫、android.enableJetifier等。
在現(xiàn)在比較流行的組件化開發(fā)中织盼,module是application還是library的開關(guān)通常也會配置在這里杨何。
local.properties(SDK Location)
這個文件中默認(rèn)配置了本地的sdk酱塔、ndk路徑。該文件的header中寫到:
This file must NOT be checked into Version Control Systems
然而危虱,這個文件很多時候并不會被VCS忽略羊娃,所以需要手動將它排除。因此埃跷,在把敏感信息配置在這個文件中時蕊玷,我們要確保它沒有被VCS收錄。
系統(tǒng)環(huán)境變量
除了上述3種配置文件之外弥雹,某些情況下垃帅,我們還可以使用系統(tǒng)環(huán)境變量來配置敏感信息。但是由于它是系統(tǒng)級的剪勿,某些情況下可能會無法正常讀取贸诚,甚至極端情況下會因?yàn)?strong>配置錯誤,導(dǎo)致系統(tǒng)宕機(jī)窗宦。所以赦颇,除非不得不配置在系統(tǒng)環(huán)境變量中,否則建議不要配置成系統(tǒng)環(huán)境變量赴涵。
讀取上述配置文件
在上一部分媒怯,我們了解了在一個 Android 項(xiàng)目中可以使用到的配置文件類型,現(xiàn)在來看一下髓窜,當(dāng)配置完成之后扇苞,我們怎么讀取使用這些配置。
gradle.properties(Global AND Project)
- 在任意.gradle文件中寄纵,我們可以通過getProperties().get("KEY_NAME")方式來讀取參數(shù)值
def getRepositoryUsername() {
return getProperties().get('bintray.user')
}
def getRepositoryPassphrase() {
return getProperties().get('bintray.gpg.password')
}
def getApiKey() {
return getProperties().get("bintray.apikey")
}
- 在Android項(xiàng)目的build.gradle中鳖敷,可以直接用KEY來獲取參數(shù)值
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類去手動加載它定踱,然后讀取其中的參數(shù)
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")
系統(tǒng)環(huán)境變量
雖然不建議這種配置方式,但是還是簡單地介紹下讀取方法恃鞋,由于它是系統(tǒng)級參數(shù)崖媚,所以在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")
}
}
最佳實(shí)踐
在上文中介紹了不同的配置文件以及它的讀取方法恤浪。最后畅哑,我想介紹一下在這次封裝分享庫時的一些最佳實(shí)踐
- 不同項(xiàng)目間通用的配置建議放在Global Properties中,如Bintray水由、Nexus賬號信息
- 項(xiàng)目專有的敏感信息荠呐,如微信\騰訊\微博開放平臺的KEY建議放在local.properties中
- Project Properties中只存放不敏感的參數(shù)
- 除非必須,否則不要使用系統(tǒng)環(huán)境變量
末尾
安利一下使用kotlin語言封裝的分享庫RxShare,使用RxJava實(shí)現(xiàn)一行代碼完成分享泥张。