大家好,我是光源。
在《大幅提高Android開發(fā)效率之Android項(xiàng)目模板化(上)》中我們了解了如何用 Android Studio Template 大幅減少寫業(yè)務(wù)代碼前的工作量,同時(shí)也稍微提了下用 Live Template 減少寫業(yè)務(wù)代碼過程中的“樣板式代碼”。
可能有朋友會(huì)問,我們這么緊張這點(diǎn)效率真的必要么?
這個(gè)問題我先不回答,我們先來看看一個(gè)場(chǎng)景:寫一個(gè)單例。
單例模式應(yīng)該是開發(fā)過程中最常見的設(shè)計(jì)模式之一了。寫單例前總得先糾結(jié)一下吧,單例模式這么多種實(shí)現(xiàn)方式該用哪種好呢?選定了實(shí)現(xiàn)方式后,老老實(shí)實(shí)寫一堆代碼,然后你會(huì)突然發(fā)現(xiàn)除了類名不一樣外,其他代碼都是一模一樣,這時(shí)你心里會(huì)不會(huì)隱隱約約覺得這是可以優(yōu)化的?
我不知道你完成單例模式的實(shí)現(xiàn)需要多長時(shí)間,但我告訴你,我們可以用一秒來搞定,你會(huì)不會(huì)覺得老老實(shí)實(shí)寫代碼的自己很傻?
這就是 Live Template 的第一個(gè)作用,提高編碼效率。
再接著上面的話題,又有人吐槽另一個(gè)細(xì)節(jié)了,一般有點(diǎn)年頭的程序員對(duì)于單例模式都有自己的一個(gè)默認(rèn)實(shí)現(xiàn)方式,不需要花時(shí)間去糾結(jié)吧?
這話不假,像我就默認(rèn)使用內(nèi)部靜態(tài)類的方式實(shí)現(xiàn)單例。但是你有沒有想過,項(xiàng)目開發(fā)是一個(gè)團(tuán)隊(duì)協(xié)作的過程,就算個(gè)人不糾結(jié),但多人開發(fā)情況下,要么每個(gè)人用自己的一套實(shí)現(xiàn)方式造成代碼風(fēng)格不統(tǒng)一,要么同事還是得事先通氣、詢問用哪種好。(編碼規(guī)范文檔也不會(huì)事無巨細(xì)把這類問題也事先規(guī)定好的)
再思考一下,很多有多方案且不屬于編碼規(guī)范的場(chǎng)景,我們又要怎么去統(tǒng)一呢?
答案還是用 Live Template。例如,Android 開發(fā)中,我們應(yīng)該使 Message.obtain() 來獲取一個(gè) Message 實(shí)例,而不是去 new 一個(gè),那么我們完全可以定一個(gè) getMsg 的 Live Template,大家只要是用 getMsg 的,可以嚴(yán)格保證統(tǒng)一性——這就是 Live Template 的另一個(gè)作用了,保持項(xiàng)目中非編碼性質(zhì)的代碼風(fēng)格統(tǒng)一。(編碼性質(zhì)的代碼風(fēng)格統(tǒng)一果斷用編碼規(guī)范文檔來實(shí)現(xiàn)了)
大家看到這里一定已經(jīng)對(duì) Live Template 有了一定的重視與好奇了吧,別著急,下面上正餐。
一、Live Template 簡介
何為 Live template ?直譯是“實(shí)時(shí)模板”,它的機(jī)制簡單地說就是提前定義好一些通用的代碼片段在編寫代碼時(shí)插入編輯器,使用方法類似代碼補(bǔ)全,默認(rèn)快捷方式是 Tab 鍵(不同平臺(tái)不同版本可能有差異)。本文將根據(jù) Android Studio 1.5+ 版本介紹 Live template 相關(guān)內(nèi)容。
進(jìn)入 Settings/Preferences -> Editor -> Live Templates,可以看到當(dāng)前已經(jīng)有的的模板組。

可以看到,默認(rèn)情況下已經(jīng)有一些模板存在。
打開分組的某個(gè)具體模板,可以看到一個(gè)模板包含了縮寫、描述、內(nèi)容三塊。

在編寫代碼的過程中輸入模板縮寫,按下 Tab 鍵,對(duì)應(yīng)的代碼片段就插入到當(dāng)前位置。
以上就是 Live Template 的簡單使用,基本與普通代碼補(bǔ)全沒啥差別,特別簡單實(shí)用。
當(dāng)然,默認(rèn)的模板雖然不少,但我們不會(huì)止步于使用默認(rèn)的模板,下面說一說如何自定義模板。
二、自定義 template
第一步 創(chuàng)建新模板
進(jìn)入 Settings/Preferences -> Editor -> Live Templates,選擇某個(gè)分組,點(diǎn)擊右上角的 “+” 號(hào),選擇 Live Template。
第二步 選擇模板適用范圍
點(diǎn)擊下方的 “Define”,選擇適用范圍。如適用于 class 文件就選 java ,適用于 xml 文件就 xml。
選定了范圍后,在范圍之外的文件則無法使用該模板。例如 Android XML 分組的“l(fā)h”模板選定了 xml,則在 class 文件中是無法使用的。
第三步 填寫內(nèi)容
如圖二所示,一個(gè)模板包括模板縮寫、描述、內(nèi)容三塊。
模板縮寫一方面是模板的名稱,另一方面是 Live Template 的觸發(fā)標(biāo)識(shí),命名上建議盡量簡潔,同時(shí)不要與普通類名、方法名等相同。
描述是模板的詳細(xì)描述,在提示中會(huì)顯示給用戶。
內(nèi)容是模板的具體定義,由普通代碼和變量組成。
模板內(nèi)容除了寫死的內(nèi)容外,還可以聲明和使用變量。變量形式為 $<variable_name>$ 。通過點(diǎn)擊下圖中的“Edit variables”按鈕打開變量定義窗口我們就可以開始創(chuàng)建當(dāng)前模板的變量。

- Name 變量名,對(duì)應(yīng) variable_name
- Expression 變量的表現(xiàn)
- Default value 默認(rèn)值
- Skip if defined 是否跳過編輯
編輯器已經(jīng)事先定義好 Expression 的一些方法, 部分常用方法如下:
| 方法 | 描述 |
|---|---|
| annotated("annotation qname") | 注解 |
| arrayVariable() | 集合變量 |
| className(sClassName) | 當(dāng)前類名 |
| classNameComplete() | 當(dāng)前完整類名 |
| complete() | 代碼補(bǔ)全 |
| componentTypeOf (<array variable or array type>) | 集合內(nèi)的元素類型 |
| date(sDate) | 系統(tǒng)當(dāng)前日期 |
| expectedType() | 所需結(jié)果的類型,這個(gè)在類型轉(zhuǎn)換中特別適用 |
| fileName(sFileName) | 帶擴(kuò)展名的文件名 |
| iterableComponentType(<ArrayOrIterable>) | 可遍歷的集合或數(shù)組類型 |
| lineNumber() | 行號(hào) |
| methodName() | 方法名 |
| methodReturnType() | 方法返回類型 |
| suggestIndexName() | 建議的索引名(i/j 等) |
| suggestVariableName() | 建議的變量名 |
| time(sSystemTime) | 系統(tǒng)時(shí)間 |
| typeOfVariable(VAR) | 變量類型 |
| user() | 當(dāng)前用戶名 |
(詳見 https://www.jetbrains.com/help/idea/2016.1/live-template-variables.html#predefined_functions )
三、舉個(gè)例子
眾所周知,單例是程序開發(fā)中最常用的模式之一,雖然有多種實(shí)現(xiàn)方案,但不管選擇哪種都避免不了重復(fù)寫一些“樣板代碼”,而這種場(chǎng)景就可以用live template 來解決了。接下來我們用創(chuàng)建單例模式的模板來具體說明如何自定義模板。
進(jìn)入
Settings/Preferences->Editor->Live Templates,選擇某個(gè)分組,點(diǎn)擊右上角的“+” 號(hào),選擇Live Template。選定適用范圍為
java。填上縮寫為 singleTon,描述為單例模式。然后把以下代碼拷貝到模板內(nèi)容中:
private static class SingleTonHolder {
private static final $class$ INSTANCE = new $class$();
}
public static $class$ getInstance() {
return SingleTonHolder.INSTANCE;
}
private $class$() {
}
這里定義了 class 變量,需要點(diǎn)擊 edit variables 創(chuàng)建該變量,變量名為 class,Expression 選擇 className() 。點(diǎn)擊 OK 保存。
創(chuàng)建某個(gè) class 后,輸入
singleTon,按下 tab 鍵就可以看到單例模板。
四、Live Template 的導(dǎo)出與導(dǎo)入
第一種方法是,創(chuàng)建完模板后模板數(shù)據(jù)會(huì)以XML的形式存儲(chǔ)在 android studio config\templates 目錄下,window下為 C:\Users\\<user>\\.AndroidStudiox.x\config\templates (user為你的計(jì)算機(jī)用戶名), mac下為
~/Library/Preferences/AndroidStudiox.x/templates ,將其中的文件拷貝出即可導(dǎo)出;同理可知,導(dǎo)入時(shí)將已定義好的xml文件放到相同目錄下,即可完成導(dǎo)入。
第二種方案是,通過 File -> Export Settings 和 Import Settings,只選中 Live Templates。
五、項(xiàng)目實(shí)踐
對(duì)于具體的項(xiàng)目而言,自定義 Live Template 可以分成兩部分,一部分是相對(duì)通用的模板,作為默認(rèn)模板的補(bǔ)充,比如上文中的單例模式模板;另一部分是跟項(xiàng)目邏輯深度相關(guān)的模板,比如使用項(xiàng)目中自定義的LogUtil而不是普通的Log來打 log 。
上文中已經(jīng)給出自定義通用模板的例子,這里再給出項(xiàng)目相關(guān)模板的示例。
例如,項(xiàng)目內(nèi)部有 toast 工具類來顯示一個(gè) toast,定義一個(gè)名為“xxtoast”的模板(避免與普通toast沖突,加上前綴),內(nèi)容是
ToastUtil.makeShortToast($strRes$);
最后,將這些自定義模板導(dǎo)出放到 gitlab 上,其他同事只需要將這些文件 clone 到對(duì)應(yīng)目錄下,即可直接使用。
小工具
有一個(gè)叫做 exynap 的 Anroid Studio 插件可以很方便搜索、創(chuàng)建、使用代碼片段(與 Live Template 不共享),感興趣的朋友可以看看。
六,參考資料
https://www.jetbrains.com/help/idea/2016.2/live-templates.html