原文地址: https://juejin.im/post/5c7339c56fb9a049e12ad6d6php
CV 工程師你好,如下內容會讓你感受到不適,慎入!html
在平時的開發工做中,咱們常常將一個地方的代碼,複製粘貼到另一個地方,俗稱搬磚,搬磚搬多了,做爲一個資深的挨踢民工,不免會總結一些提升生產力的搬磚經驗java
Android Studio 模板是個提升生產力的好東西,使用過 MVPArms 的朋友,都應該使用過我提供的配套模板,使用該套模板,一鍵便可生成整個頁面須要的全部文件,甚至還能夠一鍵生成整個 Module,真正的解放了你們的雙手,讓你們的雙手能夠去作更多熱愛的事情android
Android Stuidio 模板一共有 4 種類型,分別對應不一樣的功能,我先來簡單介紹下這 4 種模板,最後再着重介紹下一鍵生成 Module 的模板,由於前面 3 種模板在網上有太多優秀的教程了,而 Module 模板的資料很是少,我再重複寫一遍前 3 種模板的教程也不必定有別人寫得好,意義並不大,因此我前面只作簡單介紹,後面會貼出一些教程連接,沒了解過的就當科普了,瞭解過的就直接跳過git
如今還差幾個 star 就超過 Mozilla 在模板語言 Freemarker 中排名 star 全球第一了,讓我得瑟一下😏github
Live Templates 的功能主要是根據關鍵字快速生成代碼塊bash
在設置中找到 Live Templates,點擊紅框中的按鈕 "+",便可新建 Live Templatesapp
File Templates 顧名思義,主要功能就是一鍵生成單個文件框架
在設置中找到 File and Code Templates,點擊紅框中的按鈕 "+",便可新建 File Templates組件化
Activity Templates 能夠一鍵生成多個文件,但不光能夠生成 Activity 文件,還能夠根據需求生成任何 Java 文件、XML 文件以及其餘類型的文件
新建 Activity Templates 要比上面的兩個模板複雜的多,須要使用到 FreeMarker,感興趣的朋友,能夠看看我開源的 Activity Templates,稍微修改一下就能應用到本身的項目當中
module Templates 能夠一鍵生成 Module 以及 Module 中所須要的全部文件
module Templates 也是使用 FreeMarker 建立的,若是你能理解 Activity Templates,那你也能夠快速的新建一個 module Templates
不知道你們瞭解過一鍵生成 Module 的 Android Stuidio 模板嗎,這種類型的模板我在網上沒搜到有相關的開源庫和文章,因此我就本身研究了一段時間,在去年就開源給了 MVPArms 的使用者
Module Templates 其實要比 Activity Templates 簡單不少,由於 Module Templates 的某些限制,致使它的配置面板不能自定義一些新增的功能,因此複雜性下降不少,可是功能性和靈活性就要弱於 Activity Templates,不過即便這樣也能知足咱們大部分的需求了
Android Studio 中全部的 module Templates 都放在 gradle-projects 這個目錄中(Android Studio 安裝目錄/plugins/android/lib/templates/gradle-projects),若是按照不少教程中對 Activity Templates 學習方法的描述,咱們應該按照和 Activity Templates 同樣的學習方式,打開 gradle-projects 目錄中的 NewAndroidModule 進行學習
可是我能夠告訴你們,在你沒有足夠經驗的狀況下,最好不要這樣作,由於這個文件夾中包含着 Android Studio 建立 Android Module 所須要的全部文件和代碼,裏面比較複雜,有不少判斷條件,不少東西對你的項目來講都用不到,在學習時會耽誤你不少時間
因此爲了讓你們快速上手,我就用我已經開源的 module Templates 做爲學習案例,裏面的全部文件和代碼都是通過我篩選事後提取出來的,很是易於你們學習和理解
NewArmsComponent
├── root
│ ├── res //Module 中的資源文件都放這裏
│ ├── ├── anim
│ ├── ├── layout
│ ├── ├── mipmap-hdpi
│ ├── ├── mipmap-xhdpi
│ ├── ├── mipmap-xxhdpi
│ ├── ├── mipmap-xxxhdpi
│ ├── ├── values
│ ├── src/app_package //Module 中的源文件模板都放這裏
│ ├── ├── ActivityLifecycleCallbacksImpl.java.ftl
│ ├── ├── Api.java.ftl
│ ├── ├── AppLifecyclesImpl.java.ftl
│ ├── ├── ...
│ ├── test/app_package //Module 中的測試文件模板都放這裏
│ ├── ├── ExampleInstrumentedTest.java.ftl
│ ├── ├── ExampleUnitTest.java.ftl
│ ├── AndroidManifest.xml.ftl //AndroidManifest.xml 模板文件
│ ├── CMakeLists.txt.ftl //不用 CMake 能夠忽略
│ ├── build.gradle.ftl //App build.gradle 模板文件
│ ├── native-lib.cpp.ftl //不用 C 能夠忽略
│ ├── root-build.gradle.ftl //根目錄 build.gradle 模板文件
│ ├── settings.gradle.ftl //settings.gradle 模板文件
├── globals.xml.ftl
├── recipe.xml.ftl
├── template.xml
├── template_new_project.png
複製代碼
root 文件夾下包含的是生成 Module 所須要的模板文件,template_new_project.png 是模板的封面圖,globals.xml.ftl 咱們暫時用不到,recipe.xml.ftl、template.xml 這兩個文件存放的是模板的配置參數,是整個模板的核心文件,咱們來看看這兩個文件
template.xml 放置的是配置面板的參數,配置面板是什麼東西?看下圖
module Templates 和 Activity Templates 的配置面板不同,Activity Templates 能夠任意修改和新增配置面板中的項目,可是 module Templates 不能夠,只能固定爲圖中的這四項
看看 template.xml 裏面的內容
<?xml version="1.0"?>
<template format="5" revision="2" name="MVPArms Module" description="Creates a new MVPArms Module.">
<category value="Application" />
<formfactor value="Things" />
----------------------- 分割線 -----------------------
<thumbs>
<thumb>template_new_project.png</thumb>
</thumbs>
<parameter id="packageName" name="Package name" type="string" constraints="app_package|nonempty" default="com.mycompany.myapp" />
...
<globals file="globals.xml.ftl" />
<execute file="recipe.xml.ftl" />
</template>
複製代碼
只用看分割線以上的標籤便可,下面的標籤基本用不上,每一個 parameter 標籤在配置面板中都對應一個項目,但 parameter 標籤只在 Activity Templates 中能夠任意修改和新增,在 module Templates 中的任何修改和新增都是無效的,這點你們能夠試試
name 標籤和 description 標籤顧名思義,這就不用多解釋了,category 標籤固定爲 Application 便可
這裏要特別要提一下 formfactor 標籤,在 NewAndroidModule 中,formfactor 標籤的值爲 Mobile,最開始我也和它同樣,將值賦爲 Mobile,結果發現沒法生成文件,我想多是 Android Studio 只容許存在一個 Android 的 Module 模板,我又試着改爲了 TV、Glass、Wear ...,發現都不完美,要不是沒法生成文件,要不就生成太多不須要的文件,最後改爲 Things 後,效果就接近完美了
recipe.xml.ftl 的功能就是告訴模板引擎,你打算怎麼處理你的模板文件
<?xml version="1.0"?>
<!-- TODO: check include Cpp support; add driver module template -->
<recipe>
<mkdir at="${escapeXmlAttribute(projectOut)}/libs" />
<mkdir at="${escapeXmlAttribute(resOut)}/anim" />
<mkdir at="${projectOut}/src/main/java/${slashedPackageName(packageName)}/app/utils" />
<merge from="root/settings.gradle.ftl" to="${escapeXmlAttribute(topOut)}/settings.gradle" />
<merge from="root/root-build.gradle.ftl" to="${escapeXmlAttribute(topOut)}/build.gradle" />
<copy from="root/res/mipmap-hdpi/ic_launcher.png" to="${escapeXmlAttribute(resOut)}/mipmap-hdpi/ic_launcher.png" />
<copy from="root/res/mipmap-xhdpi/ic_launcher.png" to="${escapeXmlAttribute(resOut)}/mipmap-xhdpi/ic_launcher.png" />
<copy from="root/res/mipmap-xxhdpi/ic_launcher.png" to="${escapeXmlAttribute(resOut)}/mipmap-xxhdpi/ic_launcher.png" />
<copy from="root/res/mipmap-xxxhdpi/ic_launcher.png" to="${escapeXmlAttribute(resOut)}/mipmap-xxxhdpi/ic_launcher.png" />
<instantiate from="root/build.gradle.ftl" to="${escapeXmlAttribute(projectOut)}/build.gradle" />
<instantiate from="root/AndroidManifest.xml.ftl" to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
<instantiate from="root/res/values/styles.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/styles.xml" />
<instantiate from="root/src/app_package/GlobalConfiguration.java.ftl" to="${projectOut}/src/main/java/${slashedPackageName(packageName)}/app/GlobalConfiguration.java" />
<open file="${projectOut}/src/main/java/${slashedPackageName(packageName)}/app/GlobalConfiguration.java" />
<instantiate from="root/src/app_package/AppLifecyclesImpl.java.ftl" to="${projectOut}/src/main/java/${slashedPackageName(packageName)}/app/AppLifecyclesImpl.java" />
<open file="${projectOut}/src/main/java/${slashedPackageName(packageName)}/app/AppLifecyclesImpl.java" />
<#if unitTestsSupported>
<instantiate from="root/test/app_package/ExampleUnitTest.java.ftl" to="${escapeXmlAttribute(unitTestOut)}/ExampleUnitTest.java" />
</#if>
</recipe>
複製代碼
Module 所須要的模板文件都放在 root 文件夾下,而使用 recipe.xml.ftl 中的標籤就是爲了告訴模版引擎,你打算將哪一個模板文件經過什麼方式放到 Module 中的什麼位置
mkdir 標籤,顧名思義,就是生成一個空的文件夾
merge 標籤中的 from 填寫模板文件的地址,to 填寫 Module 中的目標位置,merge 標籤會將 from 中填寫的模板文件,放到 to 中填寫的目標位置上,若是目標位置已經存在一個相同文件名的文件,則將模板文件中的所有內容複製到已經存在的文件中,不然則建立一個新的文件
copy 標籤會將 from 中填寫的文件,放到 to 中填寫的目標位置上,若是目標位置已經存在一個相同文件名的文件,則會覆蓋此文件
instantiate 標籤會將 from 中填寫的模板文件,放到 to 中填寫的目標位置上,若是目標位置已經存在一個相同文件名的文件,則會覆蓋此文件,看描述和 copy 標籤差很少,那它們的區別是什麼呢?
copy 標籤的目標對象是普通文件,也就是沒有 .ftl 後綴的文件,instantiate 標籤的目標對象是模板文件,也就是有 .ftl 後綴的文件,那有 .ftl 後綴的文件和沒有 .ftl 後綴的文件有什麼區別呢?
有 .ftl 後綴的文件中可使用 FreeMarker 語法,在生成文件時,模版引擎會根據文件中的 FreeMarker 語法對文件內容進行相應的修改,好比根據不一樣的條件生成不一樣的內容,而沒有 .ftl 後綴的文件,文件中的內容一旦肯定在生成時是沒法改變的,就如同單純的複製粘貼
${escapeXmlAttribute(resOut)} 對應的是 Module 中的 res 文件夾
${projectOut}/src/main/java/${slashedPackageName(packageName)} 對應的是包名下的根目錄
${escapeXmlAttribute(topOut)} 對應的是整個工程的根目錄
${escapeXmlAttribute(projectOut)} 對應的是 Module 的根目錄
${escapeXmlAttribute(manifestOut)} 對應的是放置 AndroidManifest.xml 的文件夾
${escapeXmlAttribute(testOut)} 對應的是 Module 中放置測試文件的文件夾
root 文件夾下模板文件的編寫也不難,由於 module Templates 沒有用到自定義變量,因此大多數狀況下,就是將你寫好的 java 文件,後面加上 .ftl 後綴便可,看看下面我貼出的源代碼連接,你很快就能上手
你若是還想學到更多的 FreeMarker 語法,能夠翻翻下面貼出的 FreeMarker 中文文檔
我給 MVPArms 寫的 Activity Templates
我給 MVPArms 寫的 module Templates
掃碼關注個人公衆號 JessYan,一塊兒學習進步,若是框架有更新,我也會在公衆號上第一時間通知你們
Hello 我叫 JessYan,若是您喜歡個人文章,能夠在如下平臺關注我
-- The end