Freeline 一款 Android平臺(tái)上的秒級(jí)編譯方案

參考: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 的使用,可以參考

Freeline DSL References。

如何升級(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,修改方法如下:

  1. 修改 project-level 的build.gradle文件,將classpath 'com.antfortune.freeline:gradle:x.x.x'修改為最新版本
  2. 在命令行中執(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 的過(guò)程中如果遇見(jiàn)了任何問(wèn)題,可以先看下文檔,或者搜索一下已有的 issue,如果還無(wú)法解決的話,可以在

Github

上給我們提 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)題怎么辦?

  1. 查看文檔

  2. 查看已有的 issue

  3. 以上兩種方法都無(wú)法解決時(shí),可以在

    Github

    上提 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):

  1. 確定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 替換,這條可以不用檢查]
  2. 確定FreelineService以及 freeline 相關(guān)組件是否正常 merge 到最終的 manifest 中,最終的 manifest 路徑在${module}/build/intermediates/manifests中;
  3. 確定python freeline.py -v與定義在 build.gradle 中的 freeline 的版本是否一致;
  4. 確定是否剛剛執(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);
  5. 確定是否開(kāi)啟了網(wǎng)絡(luò)代理導(dǎo)致127.0.0.1被重定向?
  6. 一定要先使用 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)的日志提示,到

Github

上為我們提個(gè) issue,讓我們一起來(lái)探討一下。

EOF

如果對(duì) wiki 有任何疑問(wèn)或者需要訂正的地方,歡迎聯(lián)系我們。

Freeline Document wirtten by

Yong

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容