Android Studio自定義模板:簡單自定義DeviceAdminReceiver模板

一,原有模板分析
模板存放路徑:android-studio\plugins\android\lib\templates,模板包內的文件:
(1).globals.xml.ftl 存放的是一些自定義的和引用的全局變量
<globals>     
<global id="manifestOut" value="${manifestDir}" />有manifes文件時需要   <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />有src類文件需要<global id="resOut" value="${resDir}" />用到res資源需要     
<global id="relativePackage" value="<#if relativePackage?has_content>${relativePackage}<#else>${packageName}</#if>" />包
<#include "../common/common_globals.xml.ftl" />引用的全局變量, </globals>
(2).template.xml(EmptyActivity模板爲例
(3).recipe.xml.ftl
<recipe>
<#if useFragment>     <#include "recipe_fragment.xml.ftl" /> <#else>     <#include "../common/recipe_simple.xml.ftl" /> </#if>
<merge from="root/AndroidManifest.xml.ftl"              to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
<copy from="root/res/drawable-hdpi" to="${escapeXmlAttribute(resOut)}/drawable-hdpi" /> <merge from="root/${resIn}/values/strings.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/strings.xml" />
<instantiate from="root/res/xml/device_admin_receiver.xml.ftl"              to="${escapeXmlAttribute(resOut)}/xml/device_admin_receiver.xml" /> <open file="${escapeXmlAttribute(resOut)}/xml/$device_admin_receiver.xml" />   <instantiate from="root/src/app_package/DeviceAdminReceiver.java.ftl"              to="${escapeXmlAttribute(srcOut)}/${className}.java" /> <open file="${escapeXmlAttribute(srcOut)}/${className}.java" />
</recipe>
  • <#if ...>...<#else>  ...     </#if>: if語法
  • #include:引用的文件或資源文件
  • copy :從root中copy文件到我們的目標目錄,比如我們的模板Activity需要使用一些圖標,那麼可能就需要使用copy標籤將這些圖標拷貝到我們的項目對應文件夾。
  • merge : 合併的意思,比如將我們使用到的strings.xml合併到我們的項目的stirngs.xml中
  • instantiate : 和copy類似,但是可以看到上例試將ftl->java文件的,也就是說中間會通過一個步驟,將ftl中的變量都換成對應的值,那麼完整的流程是ftl->freemarker process -> java
  • open:在代碼生成後,打開指定的文件,比如我們新建一個Activity後,默認就會將該Activity打開。
內部機制:聲明變量:global.xml.ftl-----獲取參數:template.xml-----模板事件:root目錄-----模板變現:recipe.xml.ftl
變現流程:ftl->freemarker process->項目中的代碼/資源/文件
二,簡單自定義模板:DeviceAdminReceiver
1,copy一份BroadcastReceiver模板命名爲DeviceAdminReceiver,(個人喜好使用Notepad++編輯)
2,修改\android-studio\plugins\android\lib\templates\other\BroadcastReceiver.java.ftl,文件名和文件中的BroadcastReceiver替換爲DeviceAdminReceiver,\Android\android-studio\plugins\android\lib\templates\other\DeviceAdminReceiver.java.ftl:
package ${packageName};
import android.app.admin.DeviceAdminReceiver;
public class ${className} extends DeviceAdminReceiver {
    public ${className}() {
    }
//代碼
}

3,創建\android-studio\plugins\android\lib\templates\other\DeviceAdminReceiver\root\res\xml文件夾,創建一個管理配置文件device_admin_receiver.xml.ftl:
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <limit-password />
    <watch-login />
    <reset-password />
    <force-lock />
    <wipe-data />
    <expire-password />
    <encrypted-storage />
    <disable-camera />
  </uses-policies>
</device-admin>
4,修改\android-studio\plugins\android\lib\templates\other\DeviceAdminReceiver\root\AndroidManifest.xml.ftl文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
    <application>
<receiver android:name="${relativePackage}.${className}"
            android:exported="${isExported?string}"
            android:enabled="${isEnabled?string}" 
            android:label="組件名字"
            android:permission="android.permission.BIND_DEVICE_ADMIN" >
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/device_admin_receiver" />
            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

5,修改globals.xml.ftl文件,這時候我們應該明白增加了哪些內容,分析原來的變量聲明,有manifestOut,srcOut,relativePackage,而我們增加使用了res資源文件,相比較於srcOut,我們應該也聲明resOut,怎麼聲明:參考其他模板。得到的globals.xml.ftl爲:
<?xml version="1.0"?>
<globals>
    <global id="manifestOut" value="${manifestDir}" />
    <global id="srcOut" value="${srcDir}/${slashedPackageName(packageName)}" />
<global id="resOut" value="${resDir}" />
    <global id="relativePackage" value="<#if relativePackage?has_content>${relativePackage}<#else>${packageName}</#if>" />
</globals>

6,修改template.xml文件,參考其他模板和原模板界面顯示稍微改動就好了,最簡單的只需改個名字就好了,這裏除名字外,我修改了兩處,
一處增加了類別屬性,也爲另一個BroadcastReceiver增加了屬性,這個效果在上面第四張圖可以看到,Other下面增加了個Receiver,Receiver包含兩個模板;另一處增加了package塊,下面就可以看到效果
<?xml version="1.0"?>
<template
    format="5"
    revision="3"
    name="DeviceAdminReceiver"
    description="Creates a new DeviceAdminReceiver component and adds it to your Android manifest.">
  <category value="Receiver" />
  <parameter
        id="className"
        name="Class Name"
        type="string"
        constraints="class|unique|nonempty"
        default="MyDeviceAdminReceiver"     
help="The name of the DeviceAdminReceiver component class to create"/>
    <parameter
        id="isExported"
        name="Exported"
        type="boolean"
        default="true"
        help="Whether or not the broadcast receiver can receive messages from sources outside its application" />
    <parameter
        id="isEnabled"
        name="Enabled"
        type="boolean"
        default="true"
        help="Whether or not the broadcast receiver can be instantiated by the system" /> 
    <parameter
            id="packageName"
            name="Package name"
            type="string"
            constraints="package"
            default="com.mycompany.myapp"/>
    <globals file="globals.xml.ftl" />
    <execute file="recipe.xml.ftl" />
</template>
7,修改recipe.xml.ftl,僅增加了個xml文件:
<?xml version="1.0"?>
<recipe>
    <merge from="root/AndroidManifest.xml.ftl"
             to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
  <instantiate from="root/res/xml/device_admin_receiver.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/xml/device_admin_receiver.xml" />
<open file="${escapeXmlAttribute(resOut)}/xml/$device_admin_receiver.xml" />  
    <instantiate from="root/src/app_package/DeviceAdminReceiver.java.ftl"
             to="${escapeXmlAttribute(srcOut)}/${className}.java" />
    <open file="${escapeXmlAttribute(srcOut)}/${className}.java" />
</recipe>
OK,仔細檢查下代碼,不然使用模板出錯了很麻煩的,我的就需要重啓android-studio。現在在項目裏創建個DeviceAdminReceiver:
嗯,代碼就沒啥好貼的了,以後使用中再根據需要向模板裏面添加功能

發佈了38 篇原創文章 · 獲贊 71 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章