KeyStore
上一篇中有一個(gè)遺留的問題,就是使用Eclipse的keystore問題总寒,事實(shí)證明是可以直接使用的扶歪。需要注意的是,在Eclipse中設(shè)置Custom debug keystore時(shí)是不需要輸入密碼等信息的摄闸,這可能會(huì)產(chǎn)生誤導(dǎo)善镰。其實(shí)每個(gè)keystore生成時(shí)都需要設(shè)定密碼等信息的。而在AS中年枕,設(shè)置keystore時(shí)輸入密碼變成了必要步驟炫欺。
使用已有keystore
- 點(diǎn)擊File->Project Structure,在Modules部分選中要簽名的module熏兄,進(jìn)入右側(cè)Signing的tab欄品洛,點(diǎn)擊“+”號新建一個(gè)配置树姨。
- Name隨意填寫;Store File選擇已有keystore路徑桥状;其余的填寫生成此keystore時(shí)的對應(yīng)信息帽揪。這里提一下,Android自動(dòng)生成的keystore信息如下:
Keystore name: “debug.keystore”
Keystore password: “android”
Key alias: “androiddebugkey”
Key password: “android”
CN: “CN=Android Debug,O=Android,C=US” -
完成后切換到Build Types的tab中辅斟,在這里配置debug版和release版分別使用的keystore台丛。其余不用管,只要在Signing Config中選擇剛剛配置好的簽名信息的名稱即可砾肺。完成后sync gradle,會(huì)發(fā)現(xiàn)相關(guān)信息已然添加到對應(yīng)module的build.gradle中了防嗡。
使用簽名
module打包形式
項(xiàng)目最終的形態(tài)是庫文件变汪,為了開發(fā)和展示方便,是需要一個(gè)demo蚁趁,然后demo引用我們的庫文件這種形式裙盾。為了表述方便,下文稱此庫文件為mylib他嫡。原先在eclipse中番官,mylib是以應(yīng)用項(xiàng)目的形式存在的,即可以直接生成apk來測試mylib的正確性钢属,然后通過ant腳本把測試用activity之類的排除徘熔,將必要的類打成jar包。但在AS中淆党,我暫時(shí)還沒找到實(shí)現(xiàn)類似效果的方法酷师。探索過程如下:
- 打包成aar需要
apply plugin ' com.android.library'
,而打包成apk需要apply plugin ' com.android.application'
染乌,而理論和實(shí)驗(yàn)同時(shí)表明二者無法共存山孔。因此不太可能基于同一build.gradle打包成兩種形態(tài)。 - 這樣一來荷憋,自然而然想到台颠,新寫一個(gè)腳本,也放在模塊下勒庄,當(dāng)然名稱不可為build.gradle串前。當(dāng)需要打成aar時(shí),用命令行單獨(dú)指定腳本打包锅铅。確實(shí)有這樣的命令
gradlew -b 【腳本路徑(基于項(xiàng)目根目錄)】 :app:assemble
酪呻。然而運(yùn)行過后發(fā)現(xiàn),如果指定腳本盐须,那么就不會(huì)隱式包含根目錄中的settings玩荠、local.property等文件了。就是說如果想運(yùn)行非build.gradle來打包項(xiàng)目,那么所有根目錄中的配置都要拷貝一份到新腳本中阶冈,說不定還不止于此闷尿。因此便放棄這種方式。 - 還有種想法是女坑,準(zhǔn)備兩份腳本填具,分別打aar和apk。再寫一個(gè)腳本匆骗,通過參數(shù)等控制劳景,需要打哪種類型,就將哪種的腳本改名為build.gradle拷貝到module下碉就,然后再build module盟广。這是比較通用的,因?yàn)橐騼煞N類型瓮钥,可能AndroidManifest.xml也要兩種筋量,可能也需要這么做。不過想想就麻煩碉熄,畢竟也不是非得一個(gè)項(xiàng)目打成兩種桨武,這只是為了少幾個(gè)module而已。
module間依賴
既然沒法一module兩用锈津,那么就先一module是library呀酸,另一module是apk這樣。在moduleA中更改好library的功能一姿,然后在moduleB中測試效果七咧。這樣就涉及module間依賴。在moduleB的build.gradle中的dependencies中添加compile project(':moduleA')
叮叹,這樣就可以直接在B中調(diào)用A中的功能了艾栋。這種方式注意兩個(gè)module的sdkVersion應(yīng)當(dāng)一樣,否則會(huì)報(bào)找不到類的錯(cuò)誤蛉顽。
這時(shí)其實(shí)會(huì)想到蝗砾,也許直接依賴模塊和依賴生成好的aar庫文件可能會(huì)有不同,發(fā)包前肯定要直接使用aar測試下携冤。依賴其實(shí)也可以分debug版和release版悼粮,設(shè)定debug的時(shí)候直接依賴模塊,release時(shí)使用aar即可:
debugCompile project(':moduleA')
releaseCompile (name:'moduleA', ext:'aar')
這里注意曾棕,即使僅生成debug版扣猫,release版依賴的包也都應(yīng)存在,反之亦然翘地。否則會(huì)報(bào)錯(cuò)申尤。
不過僅僅是這樣的話癌幕,還是需要先打包moduleA,再將aar拷貝到moduleB昧穿,比較麻煩勺远。希望能實(shí)現(xiàn)在build moduleB時(shí)自動(dòng)打包拷貝moduleA。解決方案探索過程如下:
- 猜想有沒有assemble project這種时鸵,如果有的話再配置下moduleA的assemble的task依賴胶逢。然而并沒找到。
- 使用task間的依賴饰潜,令moduleB的build依賴于moduleA的assemble及結(jié)果拷貝初坠。但是發(fā)現(xiàn)模塊間的task是沒法互相依賴的。如果在moduleA中新建一個(gè)task彭雾,然后在moduleB中調(diào)用某筐,是無法找到此task的。
- 在根目錄的腳本中進(jìn)行配置冠跷。沒有找到簡便的配置方法。
自定義task
暫且接受需要手動(dòng)構(gòu)建moduleA的現(xiàn)狀身诺。但是構(gòu)建完成后自動(dòng)將aar拷貝到moduleB的libs下還是可以做到的蜜托。也就是說在moduleA assemble完成后,自動(dòng)清理下moduleB的libs霉赡,然后將位于moduleA/build/outputs/aar
下的aar拷貝過去橄务,而且由于生成的aar統(tǒng)一叫app-release/app-debug,在拷貝過去后還得改下名穴亏。這就要建立一個(gè)copy task和delete task蜂挪,并實(shí)現(xiàn)rename,方法如下:
- copy task:我查到的方式都是需要新建一個(gè)task嗓化,然后傳入type:Copy棠涮,沒有說能在其他task中直接實(shí)現(xiàn)copy的。而且注意刺覆,在module下的task的路徑都是相對于此module的严肪,所以要使用其他module的路徑,注意用“../”
task copyTask(type:Copy){
from 'build/outputs/aar/app-release.aar'
into '../moduleB/libs'
rename{
String fileName->
fileName.replace("app-release","moduleA")
}
}
- delete task:
task deleteTask(type:Delete){
delete '../moduleB/libs/moduleA.aar'
}
當(dāng)然實(shí)現(xiàn)這兩個(gè)task的方式還有很多谦屑,具體可以網(wǎng)上再查下驳糯。然后設(shè)定copy依賴于delete,保證操作順序:
copyTask.dependsOn deleteTask
之后就是要設(shè)定copyTask和assemble的依賴關(guān)系了氢橙,希望是在assemble執(zhí)行完成后進(jìn)行copyTask酝枢。目前我查到的,task的調(diào)用都是通過依賴的方式悍手,如果A依賴B帘睦,那么gradle A袍患,自然會(huì)喚起對B的調(diào)用。暫時(shí)沒有發(fā)現(xiàn)像函數(shù)那樣官脓,在一個(gè)task的實(shí)現(xiàn)中調(diào)用另一個(gè)task的方式协怒。因此沒法說在assemble.doLast{}中調(diào)用下copyTask這樣。這樣的話有兩種方法:
-
copyTask.dependsOn assemble
卑笨,然后直接gradle copyTask -
assemble.doLast{}.dependsOn copyTask
孕暇,這樣gradle assemble即可
零散問題
以下是遷移過程中遇到的一些問題
-
無法復(fù)制app-debug-.aar:直接在libs中使用app-debug.aar導(dǎo)致,將其改為其他名稱即可赤兴。錯(cuò)誤原因未知妖滔。直接使用app-release.aar不會(huì)出問題。
無法復(fù)制app-debug-.aar - 在模塊中dependsOn時(shí)桶良,不可以dependsOn assembleRelease座舍,只能dependsOn assemble。所以不是所有可在gradle命令中使用的task都可以dependsOn陨帆。
-
在gradlew :app:assemble的過程中曲秉,出現(xiàn)“failed to fetch URL……”,并卡在這步很久疲牵。這個(gè)迷惑性很大承二,讓你覺得是網(wǎng)絡(luò)出了問題,而且是一直在嘗試聯(lián)網(wǎng)的狀態(tài)纲爸,需要等很久才報(bào)錯(cuò)亥鸠。這期間很可能沒耐心等待盲目去查網(wǎng)絡(luò)狀況。然而實(shí)際等錯(cuò)誤報(bào)出來识啦,其實(shí)就是找不到依賴的庫负蚊。猜想應(yīng)該是本地找不到就會(huì)聯(lián)網(wǎng)去找。然而可能就是開發(fā)者忘記導(dǎo)入了而已颓哮。
找不到庫文件 -
如果minifyEnabled為false(不混淆)家妆,而zipAlignEnabled和shrinkResourcces為true,則會(huì)報(bào)各種exception:當(dāng)模式為library時(shí)冕茅,會(huì)在transformNativeLibsWithSyncJniLibsForRelease報(bào)error揩徊;當(dāng)模式為application時(shí),在packageRelease處報(bào)resources找不到嵌赠。
library模式混淆配置錯(cuò)誤
- 刪除module塑荒,需要先在settings.gradle中移除對于相關(guān)module的聲明,移除后sync姜挺,對應(yīng)module會(huì)變灰齿税,然后就會(huì)出現(xiàn)delete鍵,此時(shí)刪除即可炊豪。
- 根據(jù)官網(wǎng)說明凌箕,AndroidManifest中的versionCode拧篮、versionName等版本信息應(yīng)移至build.gradle中。