參考:https://github.com/alibaba/freeline/blob/master/freeline-docs/zh_cn.md
Python 2.7.3 Release
Win7 Python2.7 安裝教程
Freeline 是什么?
Freeline 是一款 Android 平臺(tái)上的秒級(jí)編譯方案,能夠顯著地提高 Android 工程的編譯速度。
為什么使用 Freeline?
對(duì)于一個(gè)大型的 Android 工程來(lái)說(shuō),每次簡(jiǎn)單地修改幾行代碼都需要編譯上 5 分鐘,再等待安裝到設(shè)備上的 30 秒到 1 分鐘,再重新進(jìn)入到需要調(diào)試的 Activity。這個(gè)調(diào)試環(huán)節(jié)每天都在重復(fù)幾十次,無(wú)形之中每天都有無(wú)數(shù)的時(shí)間浪費(fèi)在上面(加班阿QAQ...
Google 推出了官方的 Instant Run,但大家都知道,這個(gè)方案有太多的 case 無(wú)法覆蓋,甚至在一些比較大型的工程上基本上無(wú)法使用。
換 Mac、加內(nèi)存、上 SSD、修改 Gradle 構(gòu)建任務(wù)、組件化開(kāi)發(fā)、遷移構(gòu)建系統(tǒng)到 buck 上等等,聰明的 Android 工程師們想過(guò)很多來(lái)加速構(gòu)建的方法,但是成本都不低。
在這樣的背景下,我們開(kāi)發(fā)了 Freeline 來(lái)加速 Android 工程的構(gòu)建。Freeline 只有極低的侵入性(我們也在研究無(wú)侵入的方案),卻能極大地提高 Android 工程師們的開(kāi)發(fā)效率,大多數(shù)增量構(gòu)建都能夠在 10 秒內(nèi),甚至 1 秒完成,基本上告別了 Gradle 的卡、慢,筆記本不再風(fēng)扇狂轉(zhuǎn)、發(fā)熱發(fā)燙。
誰(shuí)在用?
開(kāi)源至今,已有來(lái)自
BAT、新美大、今日頭條、攜程、聚美優(yōu)品等上百款 App
使用了 Freeline 來(lái)提高工程師們的開(kāi)發(fā)效率,F(xiàn)reeline 對(duì)輕量級(jí)到重量級(jí)的 Android 應(yīng)用都提供了強(qiáng)有力的增量編譯支持。
如果你也在使用 Freeline,歡迎告訴我們! ->
Freeline 的維護(hù)情況
Freeline 主工程目前主要由兩位螞蟻金服的工程師在維護(hù),Android Studio 插件目前主要由社區(qū)開(kāi)發(fā)者維護(hù)。
Freeline 從本質(zhì)上來(lái)說(shuō)是 Gradle 構(gòu)建系統(tǒng)上的 hack 解決方案,所以對(duì)于多種多樣的 Android 工程可能還存在著一些兼容性問(wèn)題(不過(guò)已經(jīng)有上百個(gè) App 驗(yàn)證過(guò) Freeline 的有效性,其實(shí)也不要太過(guò)擔(dān)心),這些兼容性問(wèn)題也是維護(hù)期間主要要解決的問(wèn)題。
未來(lái),F(xiàn)reeline 還會(huì)持續(xù)跟進(jìn)并支持每個(gè)最新的 Android 版本,如果你在使用過(guò)程中遇見(jiàn)任何問(wèn)題,歡迎向我們提 issue,我們會(huì)盡快幫忙解決。
Freeline 支持的特性
- 支持標(biāo)準(zhǔn)的多模塊 Gradle 工程的增量構(gòu)建
- 并發(fā)執(zhí)行增量編譯任務(wù)
- 進(jìn)程級(jí)別異常隔離機(jī)制
- 支持 so 動(dòng)態(tài)更新
- 支持 resource.arsc 緩存
- 支持 retrolambda
- 支持 DataBinding
- 支持各類主流注解庫(kù)(APT)
- 支持 Windows,Linux,Mac 平臺(tái)
以下列表為 Freeline 支持的熱更新情況:
| Java | drawable, layout, etc. | res/values | native so | |
|---|---|---|---|---|
| add | √ | √ | √ | √ |
| change | √ | √ | √ | √ |
| remove | √ | √ | x | - |
Freeline 已經(jīng)分別在 API 17,19,22,23的 Android 模擬器、Android 6.0 Nexus 6P 以及 Android 4.4 錘子手機(jī)上經(jīng)過(guò)測(cè)試。如果想要充分體驗(yàn) Freeline 增量編譯的速度的話,最好使用 Android 5.0+ 的設(shè)備。
開(kāi)始使用
接入前的準(zhǔn)備
對(duì)于 Windows 用戶來(lái)說(shuō),你需要提前安裝 Python 2.7+(Freeline 暫時(shí)還不支持 Python 3+),安裝完之后需要重啟一下 Android Studio。
對(duì)于 Linux/Mac 用戶,如果你已經(jīng)安裝了 Python 3+,推薦你將其alias設(shè)為python3,再單獨(dú)安裝 Python 2.7+,并作為默認(rèn)的 Python 指令,避免與 Android Studio 插件自動(dòng)運(yùn)行的python命令沖突,導(dǎo)致無(wú)法正常使用插件。
如何接入?
我們提供了兩種接入 Freeline 的方法,最簡(jiǎn)單的方法是通過(guò) Android Studio 的插件來(lái)接入(實(shí)際上是對(duì)命令行的方式做了封裝,提供自動(dòng)化的解決方案),另一種則是手工通過(guò)修改配置與執(zhí)行命令的方式來(lái)接入。
方法一:Android Studio 插件
在最新版本的 Freeline 插件中,提供了自動(dòng)化一鍵接入的方式,不需要像以前一樣手動(dòng)修改build.gradle配置文件了。
在Android Studio中,通過(guò)以下路徑Preferences → Plugins → Browse repositories,搜索“freeline”,并安裝。
直接點(diǎn)擊Run Freeline的按鈕,就可以享受Freeline帶來(lái)的開(kāi)發(fā)效率的提升啦(當(dāng)然,你可能會(huì)先需要一個(gè)較為耗時(shí)的全量編譯過(guò)程)。
第一次使用的時(shí)候,插件會(huì)自動(dòng)檢測(cè)是否安裝了 Freeline,如果沒(méi)有安裝的話會(huì)彈出提示,按照提示點(diǎn)擊“確定”,插件就會(huì)自動(dòng)為你修改配置文件,并自動(dòng)安裝 Freeline 的依賴文件。
方法二:命令行方式接入
配置 project-level 的 build.gradle,加入 freeline-gradle 的依賴:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.antfortune.freeline:gradle:x.x.x'
}
}
然后,在你的主 module 的 build.gradle 中,應(yīng)用 freeline 插件的依賴:
apply plugin: 'com.antfortune.freeline'
android {
...
}
最后,在命令行執(zhí)行以下命令來(lái)下載 freeline 的 python 和二進(jìn)制依賴。
-
Windows[CMD]:
gradlew initFreeline -
Linux/Mac:
./gradlew initFreeline
對(duì)于國(guó)內(nèi)的用戶來(lái)說(shuō),如果你的下載的時(shí)候速度很慢,你也可以加上參數(shù),執(zhí)行gradlew initFreeline -Pmirror,這樣就會(huì)從國(guó)內(nèi)鏡像地址來(lái)下載。
接入有問(wèn)題?
接入 Freeline 時(shí)有幾點(diǎn)需要注意的[編譯過(guò)程也會(huì)報(bào)錯(cuò)提醒]:
- debug 模式下不要開(kāi)啟混淆
- 如果有多個(gè) productFlavor 的話,需要配置指定 flavor
如果第一次運(yùn)行的時(shí)候出現(xiàn)了耗時(shí)長(zhǎng)達(dá)十幾分鐘的話,需要注意一下是否卡在下載 gradle 文件了。檢查的方法即手動(dòng)執(zhí)行
gradlew checkBeforeCleanBuild。如果是卡在下載 gradle 文件的話,可以查找一下網(wǎng)絡(luò)上相關(guān)的資料看下如何解決這個(gè)問(wèn)題。
其他更多關(guān)于 Freeline DSL 的使用,可以參考
如何升級(jí)?
如果你安裝了 freeline 插件的話,在 Android Studio 中通過(guò)以下路徑:Build → Freeline → Check Freeline Update即可自動(dòng)檢測(cè)新版本,點(diǎn)擊update按鈕,插件會(huì)自動(dòng)為你進(jìn)行升級(jí)。
當(dāng)然,你也可以使用命令行的方式來(lái)升級(jí) Freeline,修改方法如下:
- 修改 project-level 的
build.gradle文件,將classpath 'com.antfortune.freeline:gradle:x.x.x'修改為最新版本 - 在命令行中執(zhí)行(國(guó)內(nèi)的同學(xué)推薦加上
-Pmirror參數(shù)):-
Windows[CMD]:
gradlew initFreeline -
Linux/Mac:
./gradlew initFreeline
-
Freeline 的局限
- 第一次增量資源編譯的時(shí)候可能會(huì)有點(diǎn)慢,因?yàn)樾枰~外傳遞一個(gè)完整的資源包
- 不支持刪除帶id的資源,否則可能導(dǎo)致aapt編譯出錯(cuò)
- 暫不支持抽象類的增量編譯
- 我們正在嘗試解決這個(gè)問(wèn)題
- 部分 APT 插件可能需要單獨(dú)適配
- 絕大部分 APT 插件還是都支持的
- 不支持開(kāi)啟 Jack 編譯
- 想要使用 lambda 的話,先使用 Retrolambda 吧
- 不支持 Kotlin / Groovy / Scala
-
能夠支持這幾個(gè)基于 JVM 的語(yǔ)言的工具叫做
JRebel for Android,你可以看看
-
Freeline 原理
Freeline 本質(zhì)上是熱更新技術(shù)在編譯期的運(yùn)用,通過(guò)對(duì)同一個(gè) apk 進(jìn)行持續(xù)地?zé)岣聛?lái)達(dá)到增量編譯的效果?;?Freeline 進(jìn)行修改,也能夠?qū)崿F(xiàn)線上應(yīng)用的熱修復(fù)以及 A/B Test。
Freeline 與其他類似的加速構(gòu)建方案,比如 Instant Run、Buck、JRebel for Android 有什么區(qū)別呢?開(kāi)發(fā)者如何來(lái)選擇加速構(gòu)建方案呢?可以參考這個(gè)知乎回答:有什么辦法能加快Android Studio中Gradle build速度? - Yong Huang 的回答 - 知乎。
Freeline 的具體原理可參考以下文章:
感覺(jué)以下開(kāi)源項(xiàng)目為 Freeline 的順利開(kāi)發(fā)提供了幫助:
命令行工具使用
注意,以下說(shuō)明中的gradlew分別指代 Windows 環(huán)境下gradlew,Linux/Mac 環(huán)境下的./gradlew。
Gradle Task: initFreeline
主要用于下載 freeline 的二進(jìn)制依賴(包括 python 文件等)和生成工程描述文件。
在 build.gradle 中應(yīng)用了 freeline gradle 插件之后,initFreeline這個(gè)任務(wù)會(huì)被添加到 Gradle 工程的根工程上,可以執(zhí)行gradlew initFreelien來(lái)執(zhí)行這個(gè)任務(wù)。
我們也為 initFreeline 這個(gè)任務(wù)提供了多種參數(shù)方便開(kāi)發(fā)者們做一些定制化的修改。
參數(shù):
- mirror
- 使用方法:
gradlew initFreeline -Pmirror - 參數(shù)說(shuō)明:將下載鏈接指向國(guó)內(nèi)鏡像。不加參數(shù)的時(shí)候,默認(rèn)從 aws 上進(jìn)行下載,如果你所處的網(wǎng)絡(luò)環(huán)境訪問(wèn) aws 有問(wèn)題的話,加上這個(gè)參數(shù)可以讓你獲得更好的下載速度。
- 使用方法:
- freelineVersion
- 使用方法:
gradlew initFreeline -PfreelineVersion=0.8.2 - 參數(shù)說(shuō)明:下載指定版本的 freeline 依賴文件。注意,使用這個(gè)參數(shù)的時(shí)候,請(qǐng)務(wù)必保證 build.gradle 文件中配置的 freeline 版本與指定要下載的 freeline 版本的版本號(hào)是一致的,以免產(chǎn)生一些不必要的編譯錯(cuò)誤。
- 使用方法:
- freelineTargetUrl
- 使用方法:
gradlew initFreeline -PfreelineTargetUrl="http://xxx.com/freeline.zip" - 參數(shù)說(shuō)明:從指定的鏈接處下載 freeline 依賴文件。
- 使用方法:
- freelineCdnUrl
- 使用方法:
gradlew initFreeline -PfreelineCdnUrl="http://xxx.com" - 參數(shù)說(shuō)明:使用指定的鏡像處下載,適合訪問(wèn)外網(wǎng)需要白名單,在內(nèi)網(wǎng)自己搭建鏡像的同學(xué)使用
- 使用方法:
- freelineLocal
- 使用方法:
gradlew initFreeline -PfreelineLocal="your-local-freeline-path" - 參數(shù)說(shuō)明:使用已經(jīng)下載好的 freeline 依賴文件來(lái)安裝,參數(shù)指向下載好的 freeline 依賴文件的本地路徑。
- 使用方法:
Gradle Task: checkBeforeCleanBuild
主要用于生成工程描述文件,每次 freeline 全量編譯前會(huì)先執(zhí)行一下這個(gè)任務(wù)。當(dāng)你執(zhí)行 python 命令提示報(bào)錯(cuò)的時(shí)候:freeline_core.exceptions.NoConfigFoundException: xxxxxx/project_description.json not found, please execute gradlew checkBeforeCleanBuild first.,也需要先執(zhí)行一下gradlew checkBeforeCleanBuild。
Gradle Build
freeline 為了不污染日常編譯的編譯產(chǎn)物,在執(zhí)行gradlew assemble之類的編譯命令時(shí),不會(huì)啟動(dòng) freeline 植入的任務(wù)。如果你想要在命令行運(yùn)行 freeline 的任務(wù),查看 freeline 輸出的日志的話,需要在編譯命令中,加入?yún)?shù)-PfreelineBuild=true。
freeline gradle 插件會(huì)在編譯時(shí),自動(dòng)為工程加入 freeline 的 runtime 依賴(對(duì)于 release、test 版本自動(dòng)加入 no-op 版本),如果你希望能夠?qū)?freeline runtime 的源碼引入到工程中的話,需要在 freeline DSL 中加入配置,如:
freeline {
...
autoDependency false
}
然后使用 freeline 重新進(jìn)行編譯。如果要手動(dòng)在命令行進(jìn)行編譯的話,需要加入?yún)?shù):-PdisableAutoDependency=true。
freeline.py
使用 freeline 進(jìn)行編譯的主要入口,freeline 主要通過(guò) python 來(lái)實(shí)現(xiàn)跨平臺(tái)。
參數(shù):
- -h
- 使用方式:
python freeline.py -h - 參數(shù)說(shuō)明:輸出 freeline 的參數(shù)使用說(shuō)明
- 使用方式:
- -v
- 使用方式:
python freeline.py -v - 參數(shù)說(shuō)明:獲取 freeline.py 的版本號(hào)
- 使用方式:
- -f
- 使用方式:
python freeline.py -f - 參數(shù)說(shuō)明:強(qiáng)制進(jìn)行全量編譯
- 使用方式:
- -d
- 使用方式:
python freeline.py -d(注:可與各類參數(shù)疊加使用) - 參數(shù)說(shuō)明:輸出 freeline 的調(diào)試日志(注意:不是對(duì) Android 工程進(jìn)行調(diào)試)
- 使用方式:
- -w
- 使用方式:
python freeline.py -f -w - 參數(shù)說(shuō)明:讓應(yīng)用啟動(dòng)的時(shí)候等待調(diào)試工具連接(目前只支持全量編譯的時(shí)候配合使用),日常調(diào)試推薦直接使用 Android Studio 的
attach debugger to Android process
- 使用方式:
Freeline DSL
Freeline DSL 用來(lái)輔助進(jìn)行工程配置,幫助 freeline 與 Android 工程無(wú)縫集成。主要配置在 Android 的主 module 的 build.gradle 文件中,形如:
android {
...
freeline {
... // 具體的配置內(nèi)容
}
}
注意,當(dāng)涉及到在配置中定位具體的文件路徑的時(shí)候,為了便于團(tuán)隊(duì)協(xié)作共同使用同一份 build.gradle 配置文件,推薦使用類似這樣的方式,來(lái)書寫文件路徑:project.rootProject.file("your-relative-path").getAbsolutePath()
以下為具體的配置的說(shuō)明:
-
hack
- 引入版本:0.5.0,目前已廢棄
- 參數(shù)類型:boolean
- 默認(rèn)值:false
- 參數(shù)說(shuō)明:是否使用 freeline 來(lái)打包的全局開(kāi)關(guān)
-
buildScript
- 引入版本:0.5.0
- 參數(shù)類型:String
- 默認(rèn)值:gradlew :main_module:assemble{ProductFlavor}Debug
- 參數(shù)說(shuō)明:工程的全量編譯腳本,freeline 在全量打包時(shí)使用這個(gè)命令腳本來(lái)編譯出 apk 產(chǎn)物
-
productFlavor
- 引入版本:0.5.0
- 參數(shù)類型:String
- 默認(rèn)值:""
- 參數(shù)說(shuō)明:當(dāng)工程含有多個(gè) productFlavor 的時(shí)候,需要指定一個(gè) flavor。如果未指定 flavor,則可能造成編譯失敗報(bào)錯(cuò)退出,會(huì)有錯(cuò)誤日志引導(dǎo)添加這個(gè)配置參數(shù)
-
apkPath
- 引入版本:0.5.0
- 參數(shù)類型:String
- 默認(rèn)值:freeline 會(huì)在編譯過(guò)程中自動(dòng)去找到編譯產(chǎn)物 apk 的路徑
- 參數(shù)說(shuō)明:編譯產(chǎn)物 apk 的路徑,freeline 也有可能找到錯(cuò)誤的編譯產(chǎn)物路徑,這個(gè)時(shí)候可以手動(dòng)配置正確的路徑參數(shù)
-
extraResourceDependencyPaths
- 引入版本:0.5.0
- 參數(shù)類型:List[String]
- 默認(rèn)值:[]
- 參數(shù)說(shuō)明:額外的工程的資源依賴路徑。如果使用 freeline 編譯的過(guò)程中出現(xiàn)了 aapt 編譯報(bào)錯(cuò),提示資源沒(méi)找到,有可能是某些資源路徑未被 freeline 自動(dòng)檢測(cè)到,這時(shí)可以將缺失的資源路徑添加到這個(gè)參數(shù)中。注意,資源路徑只需要添加到 res 一級(jí)即可,不需要具體到 drawable/layout/.xml/.drawable 這樣的路徑
-
excludeResourceDependencyPaths
- 引入版本:0.5.0,已不需要
- 參數(shù)類型:List[String]
- 默認(rèn)值:[]
- 參數(shù)說(shuō)明:排除會(huì)導(dǎo)致重復(fù)的資源路徑。后期的版本中,通過(guò)對(duì) aapt 的修改,繞過(guò)了這個(gè)問(wèn)題,已不需要這個(gè)參數(shù)
-
excludeHackClasses
- 引入版本:0.5.0
- 參數(shù)類型:List[String]
- 默認(rèn)值:[]
- 參數(shù)說(shuō)明:打包過(guò)程中,freeline 會(huì)對(duì) class 進(jìn)行插樁,默認(rèn)會(huì)跳過(guò)父類為
android/app/Application的類。如果你有特殊需求需要繞過(guò)插樁,可以通過(guò)這個(gè)配置項(xiàng)進(jìn)行配置
-
packageName
- 引入版本:0.5.5
- 參數(shù)類型:String
- 默認(rèn)值:applicationId
- 參數(shù)說(shuō)明:freeline 默認(rèn)獲取 applicationId 作為應(yīng)用的包名。如果你有特殊需求,或者 freeline 獲取到了錯(cuò)誤的包名的話,可以通過(guò)這個(gè)配置項(xiàng)配置你指定的包名
-
launcher
- 引入版本:0.5.5
- 參數(shù)類型:String
- 默認(rèn)值:""
- 參數(shù)說(shuō)明:freeline 默認(rèn)從 AndroidManifest.xml 文件中去獲取應(yīng)用的 launcher Activity,并用于全量編譯后自動(dòng)啟動(dòng)應(yīng)用。如果 freeline 獲取的 launcher 有誤的話,可以通過(guò)這個(gè)配置項(xiàng)配置你指定的 launcher
-
applicationProxy
- 引入版本:0.7.0
- 參數(shù)類型:boolean
- 默認(rèn)值:true
- 參數(shù)說(shuō)明:為了便于快速集成,freeline 默認(rèn)會(huì)替換應(yīng)用的 Application 類,替換為 FreelineApplication。如果由于這個(gè)替換造成了 ClassNotFound 等問(wèn)題,可以將這里的值置為 false,并手動(dòng)在你的 Application 類中加入
FreelineCore.init(this);。修改后,進(jìn)行編譯之前,記得先 clean,然后再來(lái)編譯,避免無(wú)謂的錯(cuò)誤出現(xiàn)
-
autoDependency
- 引入版本:0.7.0
- 參數(shù)類型:boolean
- 默認(rèn)值:false
- 參數(shù)說(shuō)明:freeline 自動(dòng)為應(yīng)用加載了 runtime 依賴,在非 debug 的 buildType 加載的是 no-op 版本,如果你希望通過(guò)引源碼的方式來(lái)加入 runtime 依賴,或者手動(dòng)指定 runtime 的版本,需要將此配置項(xiàng)置為 true,然后再來(lái)手動(dòng)加入依賴
常見(jiàn)問(wèn)題
常見(jiàn)問(wèn)題目錄:
- 為什么叫 Freeline?
- Freeline 與 Instant Run有什么區(qū)別?
- 使用 Freeline 時(shí)遇見(jiàn)問(wèn)題怎么辦?
- 如何進(jìn)行斷點(diǎn)調(diào)試?
- 是否支持 Kotlin、Groovy、Scala 等 JVM 語(yǔ)言?
- 是否可以開(kāi)啟 Jack 來(lái)使用 Java 8 的特性?
- 是否會(huì)影響 release 打包?
- 為什么 Freeline 會(huì)進(jìn)行全量編譯?
- 不停地提示 check sync status failed /不停地全量編譯?
- Freeline "try to connect device/ connect_device_task failed."
- java.lang.UnsupportedClassVersionError: com/android/build/gradle/AppPlugin : Unsupported major.minor version 52.0
- 資源編譯出錯(cuò):Public symbol xxxx declared here is not defined.
- 為什么一啟動(dòng)就 crash 報(bào)錯(cuò) NoClassDefFoundError?
- 切換回 Android Studio 的 RUN 時(shí),編譯出錯(cuò)
- 報(bào)錯(cuò):NoConfigFoundException
- 與Genymotion自帶的adb發(fā)生沖突
- manifest merge 報(bào)錯(cuò)
- Windows 上為什么沒(méi)有類似 Linux/Mac 上的進(jìn)度條?
- 為什么一直卡在“build increment app”頁(yè)面?
- Freeline 根本沒(méi)有那么快,你們?cè)趺纯梢韵勾蹬D兀?/a>
使用 Freeline 的過(guò)程中如果遇見(jiàn)了任何問(wèn)題,可以先看下文檔,或者搜索一下已有的 issue,如果還無(wú)法解決的話,可以在
上給我們提 issue,我們會(huì)盡快幫你解決問(wèn)題。
為什么叫 Freeline?
對(duì)的!是
Freeline,而不是 FreeLine!
Freeline
是一項(xiàng)極限運(yùn)動(dòng),代表著我們對(duì)極致速度、極簡(jiǎn)、自由的追求。我們希望 Freeline 能夠簡(jiǎn)單易用,并有著極致的編譯速度。同時(shí),我們也會(huì)持續(xù)地優(yōu)化,繼續(xù)追求 Android 編譯的極致體驗(yàn)。
Freeline 與 Instant Run有什么區(qū)別?
可以參考知乎回答:有什么辦法能加快Android Studio中Gradle build速度? - Yong Huang 的回答 - 知乎
答案中對(duì)比了 Instant Run、Buck (okbuck)、JRebel for Android、Freeline 這幾種加速構(gòu)建方案。
使用 Freeline 時(shí)遇見(jiàn)問(wèn)題怎么辦?
查看文檔
查看已有的 issue
-
以上兩種方法都無(wú)法解決時(shí),可以在
上提 issue 尋求幫助
如何進(jìn)行斷點(diǎn)調(diào)試?
使用 freeline 進(jìn)行調(diào)試跟平時(shí)調(diào)試基本上是一樣的。推薦選擇 Android Studio 工具欄上的attach debugger to Android process即可進(jìn)行斷點(diǎn)調(diào)試。如果需要在 Application 的邏輯中進(jìn)行調(diào)試的話,可以使用命令python freeline.py -f -w,工程會(huì)在全量編譯結(jié)束啟動(dòng)時(shí),自動(dòng)等待 debugger 工具的連接。
注意:python freeline.py -d僅僅是輸出 freeline 的調(diào)試日志而已,并不是真的在對(duì) Android 工程進(jìn)行調(diào)試。
是否支持 Kotlin、Groovy、Scala 等 JVM 語(yǔ)言?
不支持。Freeline 基于
*.java -> *.class -> *.dex這樣的編譯鏈進(jìn)行編譯,并通過(guò) multidex 的方案進(jìn)行增量。故無(wú)法支持除 Java 之外的其他 JVM 語(yǔ)言。
是否可以開(kāi)啟 Jack 來(lái)使用 Java 8 的特性?
不支持,原因同上,Jack 改變了編譯鏈(*.java –> *.jack –> *.dex)。
是否會(huì)影響 release 打包?
Freeline 對(duì) release 打包幾乎沒(méi)有影響。Freeline 在 release 打包的時(shí)候自動(dòng)添加的是no-op的 runtime 依賴,對(duì)FreelineCore.init(this);函數(shù)是一個(gè)空實(shí)現(xiàn)。如果你開(kāi)啟了 Application 代理的話,更是基本上毫無(wú)影響,請(qǐng)放心使用。
如果你還是實(shí)在放心不下的話,可以在打 release 包的時(shí)候,把 freeline 相關(guān)的內(nèi)容注釋掉,然后 clean and build。
為什么 Freeline 會(huì)進(jìn)行全量編譯?
Freeline 在以下幾種情況下會(huì)自動(dòng)進(jìn)行全量編譯:
- 發(fā)現(xiàn) AndroidManifest.xml 有修改
- 發(fā)現(xiàn) build.gradle 文件有修改
- 發(fā)現(xiàn)有超過(guò) 20 個(gè) Java 文件有修改過(guò)(通常在使用 git 切換分支的情況會(huì)出現(xiàn))
不停地提示 check sync status failed /不停地全量編譯?
以下操作建議使用python freeline.py -d命令來(lái)查看詳細(xì)日志:
通常,freeline 在全量編譯后,會(huì)自動(dòng)進(jìn)行增量編譯,但是在以下幾種情況下,會(huì)從增量轉(zhuǎn)入全量編譯:
- 涉及到 build.gradle、settings.gradle、AndroidManifest.xml 文件有改動(dòng)
- 增量編譯時(shí),發(fā)現(xiàn)有超過(guò) 20 個(gè) java 文件出現(xiàn)改動(dòng)
也有一種情況,每次都出現(xiàn)一句日志:[WARNING] check sync status failed, a clean build will be automatically executed.
這句日志的意思是,通過(guò) adb 連接上的設(shè)備上找到了與本地編譯的項(xiàng)目相同 uuid 的應(yīng)用(通常是同個(gè)項(xiàng)目使用 freeline 打包安裝上的),但是在進(jìn)行基線校驗(yàn)的時(shí)候校驗(yàn)失敗,需要重新打包編譯。Freeline 的基線校驗(yàn)值由 apk 打包的時(shí)間與增量次數(shù)共同生成,用于保證本地編譯的版本與設(shè)備上安裝的版本是完全一致的。主要是在切換設(shè)備的時(shí)候,容易出現(xiàn)這個(gè)問(wèn)題。
正常情況下,一次全量編譯后就會(huì)恢復(fù)正常,但也有可能會(huì)反復(fù)出現(xiàn)這句日志,一直無(wú)法恢復(fù)增量編譯,這種時(shí)候首先需要檢查一下 PC 上是否連接了多臺(tái)設(shè)備,或者 Android 模擬器 + 真實(shí)設(shè)備。如果有的話,首先保持只有一臺(tái)設(shè)備或者模擬器。
如果還是反復(fù)出現(xiàn)這個(gè)日志的話,可以嘗試把手機(jī)上的 apk 先卸載了,再重新用 freeline 編譯安裝。(如果是這個(gè)原因的話,可能是 freeline 的緩存不更新的 bug 導(dǎo)致的,近期會(huì)解決)
Freeline "try to connect device/ connect_device_task failed."
排查方法如下(建議配合使用python freeline.py -d):
- 確定
FreelineCore.init(this);加入到 Application 類中,且在onCreate()下的第一行,不要根據(jù)是否在主進(jìn)程做特殊處理,否則可能導(dǎo)致FreelineService無(wú)法正常啟動(dòng);[Freeline 0.7.0+ 開(kāi)始,默認(rèn)開(kāi)啟了 Application 替換,這條可以不用檢查] - 確定
FreelineService以及 freeline 相關(guān)組件是否正常 merge 到最終的 manifest 中,最終的 manifest 路徑在${module}/build/intermediates/manifests中; - 確定
python freeline.py -v與定義在 build.gradle 中的 freeline 的版本是否一致; - 確定是否剛剛執(zhí)行了清空app數(shù)據(jù)的操作,freeline 緩存數(shù)據(jù)在
/data/data路徑,清空app數(shù)據(jù)也會(huì)導(dǎo)致連接不上的問(wèn)題(執(zhí)行 freeline 命令時(shí),通常會(huì)有句明顯的日志反復(fù)出現(xiàn):server result is -1); - 確定是否開(kāi)啟了網(wǎng)絡(luò)代理導(dǎo)致
127.0.0.1被重定向? - 一定要先使用 freeline 來(lái)打全量包,再來(lái)進(jìn)行增量,否則也會(huì)出現(xiàn)這個(gè)問(wèn)題。即,freeline 的全量編譯與android-studio自帶的RUN會(huì)存在沖突。
當(dāng)上述問(wèn)題都無(wú)法解決時(shí),有個(gè)終極的解決方案就是重啟試試...不少人通過(guò)重啟順利解決連接不上的問(wèn)題。。。
java.lang.UnsupportedClassVersionError: com/android/build/gradle/AppPlugin : Unsupported major.minor version 52.0
問(wèn)題原因,從 Android Studio 2.2 開(kāi)始,默認(rèn)使用內(nèi)置的 Java8 版本,如果你的系統(tǒng)環(huán)境變量中使用的還是 Java7 的話,就會(huì)出現(xiàn)這個(gè)問(wèn)題,解決方案就是升級(jí)系統(tǒng)的 Java 版本。
資源編譯出錯(cuò):Public symbol xxxx declared here is not defined.
Aapt 打資源包報(bào)錯(cuò)。在aapt的參數(shù)中,缺少某些未被freeline自動(dòng)識(shí)別的資源路徑,導(dǎo)致部分資源id沒(méi)有被找到。
解決方案,將缺少的資源路徑,在build.gradle的freeline DSL中加入配置項(xiàng),如:
freeline {
...
extraResourceDependencyPaths = ['/path/to/resource/directory1', '/path/to/resource/directory2']
}
注意,只需添加到res路徑即可,不需要具體到drawable、layout的具體路徑
為什么一啟動(dòng)就 crash 報(bào)錯(cuò) NoClassDefFoundError?
修改一下 build.gradle 文件,添加配置項(xiàng):
freeline {
...
applicationProxy false
}
在你的Application類中加入:
public class YourApplication extends Application {
public onCreate() {
super.onCreate();
FreelineCore.init(this);
}
}
然后clean,重新打包即可解決問(wèn)題。
切換回 Android Studio 的 RUN 時(shí),編譯出錯(cuò)
正?,F(xiàn)象。推薦先執(zhí)行gradlew clean后,再使用 Android Studio 的 RUN,就可以恢復(fù)正常了。
報(bào)錯(cuò):NoConfigFoundException
提示如:NoConfigFoundException:/path/ not found, please execute gradlew checkBeforeCleanBuild first.
terminal 執(zhí)行指令:
-
Linux/Mac:
./gradlew checkBeforeCleanBuild -
Windows:
gradlew.bat checkBeforeCleanBuild
與Genymotion自帶的adb發(fā)生沖突
$ adb devices
adb server is out of date. killing...
cannot bind 'tcp:5037'
ADB server didn't ACK
*failed to start daemon *
問(wèn)題出現(xiàn)的原因是 Genymotion 自帶了 adb 工具,會(huì)造成沖突。解決的方式是將 Genymotion 所使用的 adb 改為 androidsdk 自帶的 adb。具體可以參考:StackOverflow - How to use adb with genymotion on mac?
manifest merge 報(bào)錯(cuò)
提示如:Exception:
manifest merger failed: uses-sdk:minSdkVersion can not be smaller than 14 declared in library[com.antfortune.freeline:runtime:x.x.x]
工程的 minSdkVersion 比 freeline-runtime 來(lái)得低導(dǎo)致的,解決方案如下:
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="21"
tools:overrideLibrary="com.antfortune.freeline"/>
Windows 上為什么沒(méi)有類似 Linux/Mac 上的進(jìn)度條?
Freeline 在 Windows 上默認(rèn)開(kāi)啟 debug 模式,輸出 debug output 信息,原因是 Windows CMD 的 terminal API 無(wú)法實(shí)現(xiàn)類似的進(jìn)度條的功能,如果你知道如何實(shí)現(xiàn)的話,也歡迎給我們提交 PR :)
為什么一直卡在“build increment app”頁(yè)面?
可以搜一下 Github 上相關(guān)的 issue,基本都是與你自己的工程或者機(jī)器的環(huán)境有關(guān)。神方法:重啟試試。
Freeline 根本沒(méi)有那么快,你們?cè)趺纯梢韵勾蹬D兀?/h3>
這位朋友,歡迎你把使用 Freeline 時(shí)出現(xiàn)的日志提示,到
上為我們提個(gè) issue,讓我們一起來(lái)探討一下。
EOF
如果對(duì) wiki 有任何疑問(wèn)或者需要訂正的地方,歡迎聯(lián)系我們。
Freeline Document wirtten by