重新認識AndroidStudio和Gradle,這些都是我們應該知道的
一、Install&Settings&Update
1、Gradle
Gradle官方會不斷更新,我們可以使用本地安裝的方式,並配置path,我們就可以使用Terminal直接輸入gradle命令執行構建任務。當然如果我們想快速更新,可以修改配置檔案。 首先,修改project\gradle\warpper\gradle-wapper.properties 檔案,其中distributionUrl的值:
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
這裡實際是從網路下載配置的版本,會自動檢測,如果不是的就會下載。
然後修改 project的build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
注意:這兩個配置是一一對應的,比如gradle-2.4-all對應的就是1.3.0。後者的意思是這個project配置的gradle構建版本為1.3.0,前者的意思是這個project使用的gradle的版本為2.4。我們會發現,如果我們修改前者,如果本地沒有安裝這個版本的gradle,會自動從gradle官網下載。但是,如果我們修改後者,它會自動從jcenter()倉庫下載一些plugin之類的。
2、AS具體的安裝和更新網上有許多的詳細教程,我只想說以下三點。
-
Android Studio是Google官方基於IntelliJ IDEA開發的一款Android應用開發工具,絕逼比Eclipse強大,還沒有轉的儘快吧:
-
關閉AndroidStudio的自檢升級,如果準備好升級還是自己選擇想升級的版本升級靠譜;
-
升級前匯出AndroidStudio的配置檔案settings.jar(C:\Users\Administrator.AndroidStudio1.4\config目錄下,或者操作File|Export Setings匯出),升級後匯入Settings.jar,這樣就不需要重新配置,有必要的話給自己備份一個,說不定老天無緣無故掛了重灌很方便。
- 具體細節的配置可以閱讀,強烈建議直接開啟AS的設定視窗,多轉幾次就熟悉了裡邊的各種配置啦。也可以參考這邊文章,(1.4版本,有點舊了,差不多夠用)打造你的開發工具,settings必備
二、Gradle
1 簡述Groovy語言
Groovy是一種開發語言,是在Java平臺上的,具有向Python,Ruby語言特性的靈活動態語言,Groovy保重了這些特性像Java語法一樣被Java開發者使用。編譯最終都會轉成java的.class檔案。他們的關係如下圖。我想這大概也是Gradle構建系統為什麼要選擇Groovy的原因,它具有java語言的特性,開發者容易理解使用。一定要明白我們在build.gradle裡邊不是簡單的配置,而是直接的邏輯開發。如果你熟練掌握Groovy,那麼你在build.grale裡邊可以做任何你想做的事。
2 Gradle程式設計框架
Gradle是一個工具,同時它也是一個程式設計框架。使用這個工具可以完成app的編譯打包等工作,也可以幹別的工作!Gradle裡邊有許多不同的外掛,對應不同的工程結構、打包方式和輸出檔案型別。我們經常使用到的便是maven\java\com.android.application\android-library等。當按照要求配置好gradle的環境後,執行gradle的task,便會自動編譯打包輸出你想要的.apk.aar.jar檔案,如果你足夠牛逼,你有gradle就夠了,直接拿記事本開發;
如下圖,是Gradle的工作流程。
- Initializtion 初始化,執行settings.gradle(我們看到都是include",實際裡邊可深了)
- Hook 通過API來新增,這中間我們可以自己程式設計幹些自己想做的事情
- Configuration 解析每個project的build.gradle,確定project以及內部Task關係,形成一個有向圖
- Execution 執行任務,輸入命令 gradle xxx ,按照順序執行該task的所有依賴以自己本身
3 關於gradle的task
每個構建由一個或者多個project構成,一個project代表一個jar,一個moudle等等。一個project包含若干個task,包含多少由外掛決定,而每一個task就是更細的構建任務,比如建立一個jar、生成Javadoc、上傳aar到maven倉庫。我們可以通過執行如下命令檢視所有的task:
gradle tasks --all
當然,我們也可以在AS中可以看到所有的task,雙擊就可以執行單個的task.
當然,我們也可以在build.gradle中寫自己的task。關於詳細的task介紹可以檢視網路資料進行學習,推薦Gradle入門系列,基本花上半天到一天的時候簡單的過一遍就有一個大概的瞭解。
4 Gradle環境下Android的檔案結構
- project-name
- gradle
- module-name
- build //構建生成檔案
- intermediates//構建打包的資原始檔
- assets//資原始檔
- exploded-aar//如果我們依賴了許多的aar或者依賴工程,最終都“copy"到了這個目錄下
- mainfests//合併的mainfest
- outputs
- apk//輸出我們需要的.apk檔案
- lint-results.html//lint檢查報告
- reports
- tests//單元測試報告
- ivy.xml//moudle的配置(task任務)、依賴關係等
- intermediates//構建打包的資原始檔
- libs //本地的依賴jar包等
- src //本moudule所有的程式碼和資原始檔
- androidTest //需要android環境的單元測試,比如UI的單元測試
- Test //普通的java單元測試
- main //主渠道
- java //java code
- jni //navtive jni so
- gen
- res
- assets
- AndroidManifest.xml +build.gradle //module
- build //構建生成檔案
- build.gradle // for all module
- gradle.propeties //全域性配置檔案
- local.properties //SDK、NDK配置
- config.gradle//自定義的配置檔案
- settings.gradle//module管理
6 關於幾個buid.gradle、gradle.propeties檔案
-
build.gradle檔案(主工程的Top-level)
apply from:"config.gradle"//可以給所有的moudle引入一個配置檔案 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter()//引入遠端倉庫 maven { url MAVEN_URL }//引入自己的私有maven倉庫 } }
-
gradle.properties(全域性配置檔案)
# This can really make a significant difference if you are building a very complex project with many sub-module dependencies: #sub-moudle並行構建 org.gradle.parallel=true #後臺程序構建 org.gradle.daemon=true #私有maven倉庫地址 MAVEN_URL= http://xxx.xx.1.147:8081/nexus/content/repositories/thirdparty/
-
build.gradle(module)
apply plugin: 'com.android.application'//外掛 決定是apk\aar\jar等 android { compileSdkVersion 23 buildToolsVersion "24.0.0" // 此處註釋保持預設開啟,關閉後可使不嚴格的圖片可以通過編譯,但會導致apk包變大 //aaptOptions.cruncherEnabled = false //aaptOptions.useNewCruncher = false packagingOptions { exclude 'META-INF/NOTICE.txt'// 這裡是具體的衝突檔案全路徑 exclude 'META-INF/LICENSE.txt' } //預設配置 defaultConfig { applicationId "com.locove.meet" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" multiDexEnabled=true//65536問題 } sourceSets { main { jniLibs.srcDirs = ['libs']//重新配置路徑 } } buildTypes { release { // zipAlign優化 zipAlignEnabled true // 移除無用的resource檔案 shrinkResources false // 混淆 minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.releaseConfig } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.google.code.gson:gson:2.2.+' testCompile 'junit:junit:4.12' }
7 gradle編譯檔案和快取檔案
- gradle快取檔案:C:\Users\Administrator.gradle\caches\modules-2\files-2.1
- idea快取檔案: C:\Users\Administrator.AndroidStudio1.4
三、構建過程簡析
這裡參考了QQ音樂技術團隊Android構建過程分析 下圖是文章末尾的一張構建流程圖:
-
解壓合併資源
主要是assets目錄,res目錄,Androidmainfest.xml目錄。其中合併的時候會涉及到優先順序的問題,詳情請檢視該篇文章。
- AAPT(Android Asset Packaging Tool)打包
- R.java檔案 資源ID
- app.ap 壓縮包
- 對png圖進行優化等
- 原始碼編譯:
生成.class位元組碼,在這裡可以進行刪除無用類,位元組碼優化,重新命名(包名),還有一點就是程式碼混淆。
- 生成dex、打包簽名、zipalign
三、構建速度優化
AS編譯太慢是我們經常吐槽的,我們該做些什麼來加快編譯的速度呢?前面我們簡單的瞭解了gradle構建專案的流程。我們可以從以下幾個方面來做:
注意AS配置:
如及時更新Gradle和JDK版本、擴大AS記憶體等(修改-Xms256m)、取消AS的自更新設定,去除不經常使用的外掛等。
慎重sub-module:
減少sub-module或者將sub-module導成aar,並上傳到私有的maven倉庫就更加方便啦,每增加一個sub-module的構建的時間會增加很多。從根上解決這個問題,我們應該增加sub-module時要慎重,同時要考慮他的獨立性,與主module要完全解耦。這樣我們不會再開發的時候產品要換個ui圖也跑到sub-module裡邊修改。當我們修改了sub-module的時候,編譯器會檢測到修改重新編譯,然後copy到主工程的buid/intermediates/exploded-aar目錄下。
守護程序deamon:
當我們在gradle.peopeties中配置org.gradle.daemon=true的時候,相當於開了個程序,這樣我們構建專案的許多工作比如載入虛擬機器之類的就在該程序中完成。
並行編譯parallel:
這個適用於有多個依賴sub-module的情況下,如果單單隻有一個module實測會耗時更多。看看官方的說法:When configured, Gradle will run in incubating parallel mode.This option should only be used with decoupled projects. org.gradle.parallel=true。這裡通過增大gradle執行的java虛擬機器大小,達到多個module並行構建的目的。
依賴庫使用固定版本:
我們配置依賴的時候 如依賴V4包,com.android.support:support-v4:23.0.0+,再後邊有個+後表示依賴最新的,這樣可以保證依賴的庫有更新時能夠得到更新。但是,小編並不建議這麼做。因為每次構建都需要訪問網路去判斷是否有最新版本,這樣也是需要耗時的。我們可能需要頻繁的構建除錯,但是我們一般很少更新庫。當然,這些可以配置在你的release分支上,總之,除錯的請配置固定版本吧。
去除無用的構建任務task:
Gradle每次構建都執行了預設的許多task,其中部分task是我們不需要執行的,至少在除錯的時候不需要,我們可以把這些遮蔽掉,方法如下:
tasks.whenTaskAdded { task ->
if (task.name.contains('AndroidTest') || task.name.contains('Test')) {
task.enabled = false
}
}
巧用include:
對於我們沒有依賴的module,我們可以在settings.gradle裡邊去掉改module的include,建議寫成一行只include一個module,如下:
include:'lib1'
//include:'lib2'
這樣我們實際就只include了lib1,當我們sync或者build\clean的時候就沒有lib2的事啦,這樣解決時間。
減少構建過程中的I/O操作:I/O操作,如copy檔案,訪問git等,Debug版本配置的minSdkVersion 21+(builder faster)
Instant Run:
最後還想說幾點:
1、不僅僅只是快1mms:
這裡的每一項我都嘗試配置使用過,實際測試基本可以解決個10多mms,當然也得看你的專案當然的狀態,以及你編輯修改的東西。雖然解決下的時間不是很顯眼,但是如果用百分數來看可以提高到20%的速度你就能感受到其中的價值啦,然後再乘以你編譯的次數,絕對的節約時間。
2、元件化的優勢:
另外一點我曾在知乎上也回答過,儘量的模組化專案內容,對於一些功能特點我們都可以抽象成小元件在demo中除錯完成,然後挪到工程裡邊。這樣不僅豐富了自己的公共庫,也提高了工作效率。
3、java除錯或者說單元測試:
對於純java的業務(相信在model層裡有很多都是)我們可以通過只執行java來除錯,比如我最近在做單詞的短語匹配演算法,那麼我在除錯的時候再class裡邊寫個main方法(很low的方案),僅除錯演算法部分就好,然後實際還是要使用單元測試更憂。
四、Maven倉庫
1、Jcenter和mavenCentral
- 區別:
- jcenter比mavenCentral倉庫要全,效能優,響應要快但有一些構建還是僅存在maven裡邊。
- jcenter上傳lib流程更加簡單。
- 引數:
- group 分組
- artifact 名稱
- version 版本
2、maven私服
五、依賴以及統一依賴管理
- 依賴種類
- 庫(library)依賴
- aar
- /AndroidManifest.xml (mandatory)
- /classes.jar (mandatory)
- /res/ (mandatory)
- /R.txt (mandatory)
- /assets/ (optional)
- /libs/*.jar (optional)
- /jni//*.so (optional)
- /proguard.txt (optional)
- /lint.jar (optional)
- jar
- aar
- 工程(moudle)依賴
- 庫(library)依賴
- Dependency configurations
- compile
- runtime
- testCompile
- testRuntime
- xxxCompile
- 依賴方式
- 本地依賴(離線:AS可以配置離線,那麼遠端依賴會使用本地快取的,而不再去請求載入)
- 遠端倉庫依賴
- @aar
- 指定了檔案型別為aar
- You shouldn't need to put @aar if the pom declares the packaging as aar (which is true in your case).
- +1 自動更新最新版本(建議Release版本中使用)
- @aar
- 依賴配置
- build.gradle
- testCompile group: 'junit', name: 'junit', version: '4.+'
- compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
- compile com.tencent.bugly:crashreport:2.1.5+
- compile 'com.stubworld.core:CorelibAndroid:[email protected]'
- project Structure
- build.gradle
- 統一依賴管理實際就是將每個moudle的依賴配置寫到一個全域性的配置檔案中,方便我們管理。我們可以新增一個全域性的config.gradle,然後在全域性的build.gradle中apply一下。詳解請參考文章搭建自己的maven私服,並使用Gradle統一依賴管理
- 官方資料
五、多渠道BuildType+ProductFlavor=Build Variant
buildType稱為構建型別,ProductFlavor稱為定製產品。怎麼理解呢?buldType預設有debug和release兩個版本,而productFlavor預設是匿名的。我們可以這麼理解,buildType是我們開發需要的通用型別,比如預設的除錯、發行版本、也可以定製方便測試人員測試的版本,對於ProductFlavor就是我們需要對產品進行定製啦,不同的Product對應了獨有的部分程式碼,比如我們要開發個免費版、企業版,這裡是舉個例子,主要還是要看你的產品構成。兩者還有一個區別在於,buildType預設共享一個defaultConfig,但是不同的Product可以對應不同的xxxConfig,由此就可以擁有不同包名等。
下面教你如果給有多重依賴關係module配置多渠道,直接貼碼說明: 我們假設A依賴了B、B依賴了C
//A為主工程
productFlavors{
free{
//免費版
minSdkVersion 21
}
pay{
//付費版
minSdkVersion 14
}
}
buildTypes{
release{
resValue "string", "app_name", "CoolApp"
signingConfig signingConfigs.release
buildConfigField "String", "API_URL", '"http://api.dev.com/"'
buildConfigField "boolean", "REPORT_CRASHES", "true"
}
debug{
applicationIdSuffix ".debug"
versionNameSuffix "-debug"
resValue "string", "app_name", "CoolApp (debug)"
signingConfig signingConfigs.debug
buildConfigField "String", "API_URL", '"http://api.prod.com/"'
buildConfigField "boolean", "REPORT_CRASHES", "false"
}
}
dependencies{
freeCompile project(path:'B',configuration:'freeRelease')
freeCompile project(path:'B',configuration:'freeDebug')
payCompile project(path:'B',configuration:'payRelease')
payCompile project(path:'B',configuration:'payDebug')
}
//B為依賴工程
publishNonDefault true //依賴工程這一句很重要,不然sync不過
productFlavors{
free{
}
pay{
}
}
buildTypes{
debug{
}
release{
}
}
dependencies{
freeCompile project(path:'C',configuration:'freeRelease')
freeCompile project(path:'C',configuration:'freeDebug')
payCompile project(path:'C',configuration:'payRelease')
payCompile project(path:'C',configuration:'payDebug')
}
//在對應的module裡面新建和main平級,和productFlavors名字相同的問題夾,並且將src等放在和main相同的路徑下就ok啦,編譯不同的渠道會找不同的檔案。
- 多渠道的意義
- 可以配置不同的URL地址
- 不同的名字、版本名、ApplicationId
- 不同的簽名配置
- 不同的原始碼
- 不同的manifest
- 不同的sdk
-
小結
不同的產品要求、不同的生產環境,我們都可以通過配置多個渠道來達到我們的工作要求,省時省力。
六、Eclipse專案徹底轉為AS
-
1、策略
- 步驟一:Eclipse匯出,獲得xxx.gradle
- 步驟二:畫出依賴關係圖
- 步驟三:調整檔案結構,把檔案結果弄成標準的,用資源管理器就可
- 步驟四:修改build.gradle,修復依賴關係
- 步驟五:建立gradle統一管理(對於大專案依賴負責,常更新的還是有必要的)
-
2、坑
- R檔案不存在
平時使用的時候也會出現這種問題,好好的sync的時候,一直報R檔案找不到,clean後還是不行,我的解決方案是在settings.gradle檔案裡邊註釋掉報錯的module所有上層的include,包括自身,sync一下沒有問題。然後開啟自己,sync沒有問題,然後逐層向上開啟工程,一切ok。
-
3、技巧
- 依賴關係理清,由下至上
- 靈活使用settings.gradle,控制include,可以sync,build任何一個工程以及所依賴的工程,減少時間,方法查詢問題,提高效率
- 構建交給伺服器(如果公司有伺服器構建的話,對於大專案可以交給伺服器來編譯,解放自己的電腦來幹別的工作)
- clean、Invalidate Caches、Restart、刪除.idea、.gradle
七、 只有一個快捷鍵:Acton or option
網路上有許多的快捷鍵大全之類的,看的密密麻麻的東西我就頭暈,最後在知乎上有位大神提到AS只有一個快捷鍵,那就是Control+Shift+A,瞬間頓悟。所以後面我很少去既什麼操作快捷鍵是什麼,而只是研究快捷操作英文名是什麼?比如說定位跳轉到某一行,我只要control+shift+A,然後輸入Line,就會列出所有有關line的操作,與此同時,每次操作我都會留意下跟在後邊括號裡邊的快捷鍵是啥,如此往復迴圈一次,使用頻率高的就給記住直接的快捷鍵,沒有記住的模糊搜尋下操作指令名稱也能快速找到,如果沒有可以去keymap裡邊自定義設定。關於操作,大概總結了以下幾類:
-
1、提示
- 原始碼提示:Documentationctrl Ctrl+shilf+space 連續兩次放大檢視 再次點選縮小
- 檢視某個方法的呼叫路徑:Call Hierachy Ctrl+alt+h
- 檢視某個方法的具體內容:Definition Ctrl+Shift+I
- extends或者implement 的所有子類 chooseImplementation Ctrl+Alt+B \Ctrl+T
-
2、編輯
-
多行編輯
-
同起點:按住Alt,同時滑鼠上下走
-
不同起點:按住Shift+Alt ,同時滑鼠多處點選
-
- 自動補全:Surround ,if.else,try/catch可以使用快捷鍵Ctrl+Alt+T (Code | Surround With)
-
-
3、查詢和替換 file find goto search replace
- 開啟檔案:enter file name ctrl+shift+r 輸入檔名
- 開啟檔案-資原始檔: ctrl+alt+F12 , 按住ctrl,滑鼠點選
- 開啟一個類: enter class name ctrl+shift+t 輸入類名
- 跳轉到一個方法:File Structure Ctrl+O 輸入方法名
- 開啟某一個物件: symbol 輸入物件名
- 跳轉到某一行:line 輸入行數
- 跳轉到當期介面的實現方法:implementation(s) ctrl+t
- 全部檔案替換 Replace in path 比如你要替換整個工程真某個字串
- 書籤 bookmarks 我的總結是有限的,實際在官方文件中有分類說明:
八、程式碼檢查
- 操作 Analyze | Inspect Code | 視窗顯示
- Android
- lint
- performance
- Unused resources //沒有使用到的資源(res)
- performance
- lint
- class structure
- File can be local //可以是區域性變數的寫成了全域性變數
- Imports
- Unused import 沒有使用的import
- General
- Default File Template Usage //有些沒有使用模板的規範
- Performance issues
- 'StringBuffer'can be replaced with 'String'
- Probable bugs
- String comparison using '==', instead of 'equals()'
- 簡單舉例,也可以在面板上直接輸入文字搜尋
九、除錯
這裡不再過多敘述啦,本人實際開發中使用的也是比較基礎,不過有個技巧,當我們按住Alt鍵然後點選某一行程式碼,可以檢視到這一行程式碼的執行結果。前提是這行程式碼已經執行過啦,覺得還是挺好用的。更多可以參考Android Studio程式碼除錯大全學習。
十、 終極技巧
- 合理使用外掛:plugin
- SimpleUML
- MarkDown
- 書籤、喜歡分組(bookMarks、favorites)
-
抓屏佈局分析(LayoutInspector)
-
巨集(Edit|Macors)
這個和office辦公軟體有點類似,我們可以錄製一段操作,然後播放就可以自動執行錄製好的操作。
-
Templates(模板)
- LiveTemplates (Settings|Live Teamplates)
- .notnull 自動填充為空的判斷
- .for
- 具體的有很多,在設定面板中檢視
- FileTemplates
- SaveAsTemplates,可以將某一個class或者檔案儲存為模板,新建的時候直接生成引用。
- File and Code Templates
- File 的頭部可能有宣告作者、日期的註釋,這裡可以自動生成。
-
前後綴(Editor|Code Style|Java)
這個可以自動給變數新增一個前後綴,比如我們的成員變數常在前面加一個m。
- LiveTemplates (Settings|Live Teamplates)
-
Intentions
意圖,這裡可以根據預設的程式碼結構來填充修改程式碼,比如我們有 a.equals("A"),如果我們按 Alt+Enter,就會有一個split的提示選項,點選之後程式碼就會變成 “A".equals(a)。具體有很多,開啟設定面板自己看吧。
-
版本管理
- 分支程式碼對比 AS右下角的邊框有分支可以看,點開就可以有許多的功能。前提是已經啟用配置好git.
- Annotate
- layout佈局遍歷
- 巧用Alt+Enter
當我們的程式碼報錯的時候,當我們希望有更多功能的時候,按這個快捷鍵就會有很多驚喜。比如,我們在一個Class上使用該快捷鍵,就會有提示新增單元測試 Create Test ,然後一秒鐘新增好了單元測試類。
- 巧用Settings.gradle 我們可以通過註釋include,達到自由管理專案中各個moudle,在我們編譯出錯的時候方便查問題。
- 快捷鍵,有這個命令圖就夠啦。
- 模板 Tools/Save File as a Template
- 巧用AS無處不在的篩選排列顯示
- project裡邊的 project/android/FlattenPackages
- Find Usage 結果列表中的 write
- 以及每個工具面板中的篩選按鈕
- 巧用註解@NonNull (官方文件 Improve Code Inspection with Annotations)
- 面板區域內直接輸入搜尋
我們在很多的面板,比如左側的專案導航欄,可以直接輸入字母模糊搜尋你需要的檔案。
- LocalHistory
程式碼編輯的歷史記錄,方便找回意外丟失修改的程式碼。
-
一些有趣的task
-
根據git提交自動配置版本號
defaultConfig { # Add 10000 to move past old SVN revisions. versionCode gitCommitCount() + 10000 ?: 0 } def gitCommitCount() { try { def stdout = new ByteArrayOutputStream() exec { commandLine 'git', 'rev-list', '--count', 'HEAD' standardOutput = stdout } def commitCount = stdout.toString().trim().toInteger() return commitCount } catch (ignored) { return 0; } } def gitRevision() { try { def stdout = new ByteArrayOutputStream() exec { commandLine 'git', 'rev-list', 'HEAD', '-n', '1' standardOutput = stdout } def commitRevision = stdout.toString().trim() return commitRevision } catch (ignored) { return "(unknown revision)"; } }
-
十一、 AndroidStudio 2.2版本特性
- 設計
- 佈局編輯器
- 約束佈局
- 開發
- 改進C++支援
- 示例瀏覽器
- 構建
- Instant Run 改進
- Java 8 支援
- Open JDK 支援
- 測試
- 模擬器增加了虛擬感測器
- apk分析器
十二、總結
- Gradle是一個強大的包裝機;
- maven遠端依賴很給力;
- 快捷鍵只有一個,那就是Ctrl+Shift+A;
- 絕招有很多.套路太深,別說你不懂;
- 妹紙都是浮雲,我們天天雙眼就盯著AndroidStudio,所謂日久生情。