Instant Run

如何編譯運(yùn)行app

我們要編譯運(yùn)行一個(gè)AS工程,只需在AndroidStudio上點(diǎn)擊幾下按鈕就行了。InstantRun模式下,當(dāng)你修改一些方法和存在的資源時(shí),允許你不用編譯一個(gè)新的apk就可以立即看到修改后的效果。
編譯運(yùn)行你的app,點(diǎn)擊Run 'app'

.Andorid Studio使用Gradle進(jìn)行編譯,詢問(wèn)你運(yùn)行的目標(biāo)設(shè)備,之后會(huì)發(fā)布到改設(shè)備上。你可以自定義一些默認(rèn)的行為,如可以選擇一個(gè)自動(dòng)發(fā)布的目標(biāo)設(shè)備,可以通過(guò)修改運(yùn)行配置

修改運(yùn)行配置

運(yùn)行配置包括,運(yùn)行那個(gè)modle,打包發(fā)布,Activity啟動(dòng),目標(biāo)設(shè)備,模擬器設(shè)置,日志配置。編輯運(yùn)行配置:

  1. 選擇Run > Edit Configurations.

更改Build Variant

默認(rèn)情況下,當(dāng)你點(diǎn)擊Run 'App'的時(shí)候,Android Studio編譯debug版本的app。想要改變build variant,可以通過(guò)Build>Select Build Variant,從下拉菜單中選擇你想執(zhí)行的類型

監(jiān)控執(zhí)行過(guò)程

可以點(diǎn)擊Gradle Console

.在輸出面板中會(huì)顯示執(zhí)行task的名字,如下圖所示
The Gradle Console in Android Studio
The Gradle Console in Android Studio

如果在編譯過(guò)程中出現(xiàn)異常,消息窗口會(huì)提示出錯(cuò)信息。Gradle會(huì)給你推薦一些命令行幫助你解決問(wèn)題,例如--stacktrace--debug。如何在編譯過(guò)程中使用命令行

  1. 打開(kāi)設(shè)置
  2. 導(dǎo)航到Build,Execution,Deployment>Compiler
  3. Command-line Options輸入命令行選項(xiàng)
  4. 點(diǎn)擊確認(rèn)保存退出

關(guān)于Instant Run

Instant Run是Android Studio2.0引入的,用于減少開(kāi)發(fā)過(guò)程中等待app更新的時(shí)間。Instant Run通過(guò)patch修改的部分而不是重新打一個(gè)apk的方式來(lái)減少等待時(shí)間。

使用Instant Run,需要Android Plugin for Gradle的版本在2.0.0后,minSdkVersion>=15,要想有更好的性能,minSdkVersion>=21。

在你運(yùn)行過(guò)一次后,一個(gè)閃電圖標(biāo)會(huì)顯示在運(yùn)行按鈕

上,表明InstantRun已經(jīng)準(zhǔn)備好了,會(huì)在下次運(yùn)行時(shí)生效。

InstantRun 把你更新的代碼和資源push到你的設(shè)備上通過(guò)hot swapwarm swapcold swap。它會(huì)自動(dòng)決定用何種方式進(jìn)行push,他們的介紹直接粘貼你真的了解Instant Run嗎這篇文章。

hot swap

hot swap是所有swap方式中效率最高的一種,應(yīng)用程序不需要重新安裝,也不需要重啟就可以完成程序變更。但是hot swap不會(huì)對(duì)程序中的對(duì)象進(jìn)行重新初始化,也就是說(shuō)可能某些場(chǎng)景下需要重啟Activity才能看出具體的變更內(nèi)容。Android Studio對(duì)于hot swap這種情況默認(rèn)是重啟Activity的,當(dāng)然你也可以到設(shè)置中去改變這一默認(rèn)行為,具體路徑是 Settings -> Build, Execution, Deployment -> Instant Run -> Restart activity on code changes。

hot swap的適用條件比較少,只有一種情況會(huì)被Android Studio視為hot swap類型,就是修改一個(gè)現(xiàn)有方法中的代碼,效果如下圖所示:

可以看到,我只改動(dòng)了一個(gè)現(xiàn)有方法的內(nèi)部代碼,重新運(yùn)行后編譯和部署的速度都非常快,最關(guān)鍵的是,應(yīng)用程序并沒(méi)有重新安裝或重啟,甚至于Activity都沒(méi)有重啟(由于我進(jìn)行了上述的設(shè)置),然后修改的代碼就成功替換了。

Warm Swap

warm swap也非常快,這種swap類型同樣不需要重新安裝或重啟程序就可以完成程序變更,但是warm swap要求必須重啟Activity。你會(huì)在界面上看到屏幕很快地閃一下,同時(shí)Activity的生命周期會(huì)重新執(zhí)行。

warm swap的適用條件也比較局限,只有一種情況會(huì)被Android Studio視為warm swap類型,就是修改或刪除一個(gè)現(xiàn)有的資源文件,效果如下圖所示:

可以看到,我改動(dòng)了布局文件中的內(nèi)容,重新運(yùn)行后速度仍然很快,應(yīng)用程序并沒(méi)有重新安裝或重啟,只是Activity重啟了一下,因?yàn)橐獙⑿薷暮蟮牟季謨?nèi)容展示到界面上。

Cold Swap

cold swap相對(duì)而言就要更慢一些了,Android Studio會(huì)自動(dòng)記錄我們項(xiàng)目的每次修改,然后將修改的這部分內(nèi)容打成一個(gè)dex文件發(fā)送到手機(jī)上,盡管這種swap類型仍然不需要去安裝一個(gè)全新的APK,但是為了加載這個(gè)新的dex文件,整個(gè)應(yīng)用程序必須進(jìn)行重啟才行。另外,cold swap的工作原理是基于multidex機(jī)制來(lái)實(shí)現(xiàn)的,在不引入外部library的情況下,只有5.0及以上的設(shè)備才支持multidex,因此,如果你使用了5.0以下的設(shè)備,那么cold swap就無(wú)法工作了,這種情況會(huì)執(zhí)行最原始的完整APK安裝過(guò)程。

cold swap的適用條件非常多,下面我列出一個(gè)詳細(xì)的清單,有哪些情況會(huì)被Android Studio視為cold swap類型:

  1. 添加、刪除或修改一個(gè)注解
  2. 添加、刪除或修改一個(gè)字段
  3. 添加、刪除或修改一個(gè)方法
  4. 添加一個(gè)類
  5. 修改一個(gè)類的繼承結(jié)構(gòu)
  6. 修改一個(gè)類的接口實(shí)現(xiàn)
  7. 修改一個(gè)類的static修飾符
  8. 涉及資源文件id的改動(dòng)

那么我們還是來(lái)看一下演示效果吧,如下圖所示:


0 (2).gif

可以看到,這里我給第二個(gè)Button添加了一個(gè)新的點(diǎn)擊事件方法,添加一個(gè)方法是滿足cold swap條件的,那么我們明顯可以看出,應(yīng)用程序重新啟動(dòng)了,但是整體的速度依然很快,整個(gè)重新運(yùn)行的過(guò)程在5秒種之內(nèi)完成的,我的截圖都是實(shí)時(shí)速度,沒(méi)有進(jìn)行加速播放。

Full APK

除了滿足以上條件的其他程序變更,Instant Run目前都還不支持,主要包括以下一些情況:

  1. 改變AndroidManifest.xml文件的內(nèi)容
  2. 改變被AndroidManifest.xml文件所引用的資源,比如string.xml中的app_name
  3. 改變桌面widget的UI相關(guān)元素

當(dāng)程序變更不被Instant Run所支持時(shí),就會(huì)執(zhí)行完整的APK安裝過(guò)程,同時(shí)Android Studio會(huì)給出這樣的提示:


由于這種情況重新運(yùn)行時(shí)間比較長(zhǎng),就不給大家截圖演示了,以前我們使用低于2.0版本的Android Studio開(kāi)發(fā)時(shí),每次都是執(zhí)行的這種情況。

當(dāng)然,這只是目前的Instant Run規(guī)則,Android Studio團(tuán)隊(duì)還會(huì)一直進(jìn)行優(yōu)化,增加hot swap和warm swap的條件,減少cold swap和full apk的條件,相信未來(lái)的Android Studio會(huì)更加好用。

Rerun

盡管Instant Run盡可能地想要變得更智能,但是它也沒(méi)有時(shí)光倒流的能力。比如hot swap或者warm swap是根本不會(huì)重啟程序的,而如果你修改了一些只有在程序啟動(dòng)的時(shí)候才會(huì)初始化的代碼,那么Instant Run對(duì)此也是無(wú)能為力的,因?yàn)樾薷牡拇a根本就沒(méi)有執(zhí)行到。

針對(duì)這種情況,Android Studio專門(mén)提供了一個(gè)Rerun按鈕:


中間那個(gè)按鈕就是Rerun按鈕,使用這個(gè)按鈕來(lái)重新運(yùn)行程序,應(yīng)用程序會(huì)被強(qiáng)制重啟,從而初始化的一些代碼就能夠執(zhí)行到了。Android Studio無(wú)法得知改動(dòng)的代碼是不是在程序初始化的時(shí)候才執(zhí)行的,而我們卻可以知道,所以確保你理解了Rerun這個(gè)按鈕的作用,并在恰當(dāng)?shù)臅r(shí)機(jī)使用它。

補(bǔ)充

hot swap由于其工作原理的限制還有一些特殊問(wèn)題。hot swap會(huì)在應(yīng)用程序的內(nèi)部開(kāi)啟一個(gè)服務(wù)器,然后由Android Studio自動(dòng)計(jì)算出方法內(nèi)實(shí)現(xiàn)的變更,將變更代碼發(fā)送到服務(wù)器,服務(wù)器再利用類加載器和委托機(jī)制將新的代碼實(shí)現(xiàn)注入到現(xiàn)有應(yīng)用程序中,從而完成替換工作。

但是整個(gè)過(guò)程中,新的代碼實(shí)現(xiàn)并沒(méi)有被保存到本地,也就是說(shuō)一旦設(shè)備和Android Studio的連接斷掉了(比如拔掉數(shù)據(jù)線),我們使用hot swap替換的代碼也就隨之不見(jiàn)了。當(dāng)你再次打開(kāi)程序的時(shí)候,你會(huì)看到這樣的提示:

看到這個(gè)提示并不用感到驚奇,這就說(shuō)明你的hot swap代碼失效了,現(xiàn)在的程序仍然使用的老的代碼。遇到這種情況只需要將手機(jī)連上電腦,然后在Android Studio中重新運(yùn)行一下程序就可以解決了。另外只有在debug模式下才可能會(huì)出現(xiàn)這個(gè)提示,release模式下是不可能出現(xiàn)的,所以不用擔(dān)心這個(gè)提示會(huì)讓用戶感到困惑。

配置優(yōu)化InstantRun

通過(guò)配置DEX 資源加快編譯速度

android {
  ...
  dexOptions {
    maxProcessCount 4 // this is the default value
    javaMaxHeapSize "2g"
  }
}

Enable dexing-in-process和增量編譯

該功能需要使用Android Plugin for Gradle 2.1.0及以后的版本,為了是該功能生效,你需要設(shè)置Gradle daemon's的最大heap size至少為2048M,在可以在gradle.propertes文件加入:

org.gradle.jvmargs = -Xmx2048m

如果你已經(jīng)定義了javaMaxHeapSize在你的modle的build.gradle文件中,你需要設(shè)置daemon's的最大headp size的值為javaMaxHeapSize+1024MB。例如如果你的javaMaxHeapSize為“2g”,你需要在gradle.properties文件中設(shè)置為:

org.gradle.jvmargs = -Xmx3072m

window病毒掃描不要包含工程文件

Disable Crashlytics for your debug build variant

使用Crashlytics會(huì)引起編譯速度慢,為了提高開(kāi)發(fā)階段的效率,可以把起disable掉,disable Crashlytics:

Instant Run的局限性

部署到多個(gè)設(shè)備

由于Instant Run使用不同的技術(shù)在不同的API版本上,因而當(dāng)你把a(bǔ)pp部署到多個(gè)設(shè)備上時(shí),Android Studio會(huì)臨時(shí)關(guān)閉Instant Run功能。

多dex的APP

當(dāng)你在你的build.gradle文件里設(shè)置了multiDexEnabled trueminSdkVersion 20 or lower,這時(shí)如果你部署你的app到Android4.4(API 20)或更低版本,Android Studio會(huì)關(guān)閉Instant Run功能。

如果minSdkVersion設(shè)置為21或更高版本,Instant Run會(huì)自動(dòng)為你的app配置multidex。由于InstantRun僅在debug版本工作,如果你要發(fā)布release版,你需要手動(dòng)配置multidex。

第三方插件

Android Studio會(huì)臨時(shí)關(guān)閉java Code Coverage Library(JaCoCo) 和 ProGuard當(dāng)你使用InstantRun時(shí)。因?yàn)镮nstantRun僅在Debug上工作,因而不會(huì)影響Release編譯。

使用Instant Run構(gòu)建你的app時(shí),如果使用第三方插件進(jìn)行字節(jié)碼優(yōu)化可能會(huì)有問(wèn)題,如果你想使用Instant Run,你需要關(guān)閉字節(jié)碼優(yōu)化插件。

推送更改到多進(jìn)程的APP

InstantRun進(jìn)支持在應(yīng)用的主進(jìn)程進(jìn)行hot swaps和warm swaps。如果想要對(duì)其他進(jìn)程進(jìn)行更新,InstantRun會(huì)執(zhí)行cold swap。

關(guān)閉InstantRun功能

  1. Open the Settings or Preferences dialog.
  2. Navigate to Build, Execution, Deployment > Instant Run.
  3. Uncheck the box next to Enable Instant Run.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 什么是Instant Run? 我們都知道,Android Studio功能非常強(qiáng)大,在各個(gè)功能性方面都要優(yōu)于Ec...
    GB_speak閱讀 822評(píng)論 0 3
  • 在Instant Run剛出來(lái)的時(shí)候,反編譯源碼寫(xiě)過(guò)一篇Instant Run原理解析,但過(guò)于基于源碼,感覺(jué)沒(méi)有寫(xiě)...
    皓云觀閱讀 603評(píng)論 0 1
  • Instant Run 翻譯成中文叫即時(shí)運(yùn)行或直接運(yùn)行模板。不過(guò)我一般習(xí)慣了叫做閃電運(yùn)行,為什么這么叫?請(qǐng)看圖: ...
    Reathin閱讀 15,413評(píng)論 3 11
  • 一.做了那些有價(jià)值的事 1.跟學(xué)員得水進(jìn)行了溝通,明天付費(fèi)加入我們的社群 2.寫(xiě)了1500多字的文章 3.晚上跟默...
    王小柯閱讀 381評(píng)論 0 0
  • 0303不能再想你(一) 0304不能再想你(二) 0306不能再想你(完結(jié)) 起因 春節(jié)過(guò)完,繼續(xù)上班。 我離開(kāi)...
    一夏飄雪閱讀 362評(píng)論 0 2