【譯】移動應用開發:如何建立自定義Android程式碼模板

Knight_Davion發表於2017-12-26

介紹

這篇教程會為你展示如何建立屬於你自己的程式碼模板。大多數的Android開發者都至少一次使用過Android程式碼模板來新建工程。但是你有沒有嘗試過建立自己的Android程式碼模板? 在這篇教程中,我們將會為你展示可用於從Android Studio IDE生成包含Google Analytics配置的Android工程模板。

原始碼

這裡下載原始碼 原文連結

程式碼生成過程圖解

【譯】移動應用開發:如何建立自定義Android程式碼模板

具體建立步驟

要建立自己的模板,請確保:

  1. 你已經瞭解上述程式碼生成過程圖解;
  2. 你有一些關於FreeMarker的知識;
  3. 你有一些關於Android IDE模板格式的知識,你可以在這裡檢視相關文件。

第一步:建立Google Analytics應用程式資料夾

這是你的模板目錄,在Windows上,${android studio 安裝路徑}/plugins/android/lib/templates/,其他平臺Linux,Mac OS請自行查詢; 在GoogleAnalyticApplication資料夾中建立根資料夾和其他檔案,如下所示:

【譯】移動應用開發:如何建立自定義Android程式碼模板

第二步:建立template.xml檔案

每個模板目錄必須包含一個template.xml檔案,這其中包含有關模板的一些後設資料,包括名稱,描述,類別和使用者可見引數這些IDE將作為選項呈現給使用者。 檔案中還會在指明FreeMarker處理的recipe檔名稱和全域性變數檔案,如果除了模板引數值之外還有全域性變數應該對所有FreeMarker處理的檔案可見。 Template.xml

<?xml version="1.0"?>
<template
	format="3"
	revision="4"
	name="Google Analytics Application"
	minApi="7"
	minBuildApi="14"
	description="Creates a new application that has already Google Analytics configuration.">
	<category value="Activity" />
	<formfactor value="Mobile" />
	<parameter
		id="activityClass"
		name="Activity Name"
		type="string"
		constraints="class|unique|nonempty"
		suggest="${layoutToActivity(layoutName)}"
		default="MainActivity"
		help="The name of the activity class to create" />
	<parameter
		id="layoutName"
		name="Layout Name"
		type="string"
		constraints="layout|unique|nonempty"
		suggest="${activityToLayout(activityClass)}"
		default="activity_main"
		help="The name of the layout to create for the activity" />
	<parameter
		id="classApplication"
		name="Class extends Application"
		type="string"
		constraints="nonempty|class"
		help="The name of class that extends from Application" />
	<parameter
		constraints="nonempty|string"
		id="googleAnalyticID"
		name="Google Analytic ID"
		type="string"
		help="Id of Google Analytic" />
	<parameter
		id="dispatchPeriod"
		name="Dispatch Period"
		help="Frequency of automatic dispatch in seconds. Defaults to 30 minutes (1800 seconds)."
		type="string"
		default="1800"/>
	<parameter
		id="autoActivityTracking"
		name="Auto Activity Tracking"
		help="If true, views (Activities) will be tracked automatically. false by default."
		type="boolean"
		default="false"/>
	<!-- 128x128 thumbnails relative to template.xml -->
	<thumbs>
		<!-- default thumbnail is required -->
		<thumb>template_google_analytics.png</thumb>
	</thumbs>
	<globals file="globals.xml.ftl" />
	<execute file="recipe.xml.ftl" />
 
</template>
複製程式碼

其中的一些引數比如: activityClass, layoutName, classApplication, googleAnalyticID, dispatchPeriod, autoActivityTracking,將在建立專案時顯示在彈出視窗中。

【譯】移動應用開發:如何建立自定義Android程式碼模板

第三步:建立globals.xml.ftl檔案

這是一個可選的檔案,裡面包含全域性變數的定義,用於此模板的所有FreeMarker處理任務。 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}" />    
</globals>
複製程式碼

第四步:在root資料夾中建立相關檔案和資料夾

root資料夾中包含模板原始碼

【譯】移動應用開發:如何建立自定義Android程式碼模板

1.建立AndroidManifest.xml.ftl
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="${packageName}">
    <application
        android:name="${packageName}.${classApplication}"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.gms.analytics.globalConfigResource"
            android:resource="@xml/analytics_global_config" />
        <activity
            android:name=".activities.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
複製程式碼

其中的packageName,classApplication是在template.xml檔案中定義的。

2.建立Application.java.ftl檔案
package ${packageName};
import android.app.Application;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.Tracker;
/**
 * Created by TungDX on 5/29/2015.
 */
public class ${classApplication} extends Application {
    private static GoogleAnalytics analytics;
    private static Tracker tracker;
    @Override
    public void onCreate() {
       analytics = GoogleAnalytics.getInstance(this);
       tracker = analytics.newTracker("${googleAnalyticID}");
    }
    public static GoogleAnalytics getGoogleAnalytics() {
       return analytics;
    }
    public static Tracker getTracker() {
        return tracker;
    }
}
複製程式碼

其中的packageName,googleAnalyticID是在template.xml檔案中定義的。

3.建立MainActivity.java.ftl檔案
package ${packageName}.activities;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import ${packageName}.${classApplication};
import ${packageName}.R;
public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    protected void onStart() {
        super.onStart();
        ${classApplication}.getGoogleAnalytics().reportActivityStart(this);
    }
    @Override
    protected void onStop() {
        super.onStop();
        ${classApplication}.getGoogleAnalytics().reportActivityStop(this);
    }
}
複製程式碼

其中的packageName,classApplication是在template.xml檔案中定義的。

4.建立activity_main.xml.ftl檔案
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">
    <TextView
        android:text="@string/ready"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>
複製程式碼
5.建立strings.xml.ftl檔案
<resources>
    <#if !isNewProject>
    <string name="title_${activityToLayout(activityClass)}">${escapeXmlString(activityTitle)}</string>
    </#if>
	<string name="ready">Google Analytic is ready!</string>
</resources>
複製程式碼
6.建立dimens.xml檔案
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>
複製程式碼
7.建立recipe.xml.ftl檔案

recipe.xml檔案中包含了從該模板生成程式碼時應執行的各個命令。比如,你可以複製某些檔案或目錄,或者通過FreeMarker執行原始檔,並要求IDE在程式碼生成後開啟一個檔案。

<?xml version="1.0"?>
<recipe>
<dependency mavenUrl="com.android.support:support-v4:${targetApi}.+" />
<dependency mavenUrl="com.android.support:appcompat-v7:${targetApi}.+"/>
<dependency mavenUrl="com.google.android.gms:play-services:6+" />

<instantiate from="AndroidManifest.xml.ftl"to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />

<instantiate from="src/app_package/Application.java.ftl" to="${escapeXmlAttribute(srcOut)}/${classApplication}.java"/>

<instantiate from="src/app_package/activities/MainActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java"/>
 
<instantiate from="res/xml/analytics_global_config.xml.ftl" to="${escapeXmlAttribute(resOut)}/xml/analytics_global_config.xml"/>

<instantiate from="res/layout/activity_main.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml"/>

<copy from="res/values/dimens.xml" to="${escapeXmlAttribute(resOut)}/values/dimens.xml"/>

    <merge from="res/values/strings.xml.ftl"to="${escapeXmlAttribute(resOut)}/values/strings.xml" />   
    <open file="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java" />
    <open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
</recipe>
複製程式碼
8.檢查依賴

【譯】移動應用開發:如何建立自定義Android程式碼模板

9.檢查AndroidManifest.xml.ftl
<instantiate from="AndroidManifest.xml.ftl"          to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
複製程式碼

【譯】移動應用開發:如何建立自定義Android程式碼模板

10.檢查Application.java.ftl
<instantiate from="src/app_package/Application.java.ftl" to="${escapeXmlAttribute(srcOut)}/${classApplication}.java"/>
https://robusttechhouse.com/wp-admin/post.php?post=6937&action=edit&message=10#
複製程式碼

【譯】移動應用開發:如何建立自定義Android程式碼模板

11.檢查MainActivity.java.ftl
<instantiate from="src/app_package/activities/MainActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java"/>
複製程式碼

【譯】移動應用開發:如何建立自定義Android程式碼模板
【譯】移動應用開發:如何建立自定義Android程式碼模板

12.檢查analytics_global_config.xml.ftl
<instantiate from="res/xml/analytics_global_config.xml.ftl" to="${escapeXmlAttribute(resOut)}/xml/analytics_global_config.xml"/>
複製程式碼

【譯】移動應用開發:如何建立自定義Android程式碼模板

13.從模板中生成 activity_main.xml, dimens.xml, strings.xml檔案
<instantiate from="res/layout/activity_main.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml"/>
<copy from="res/values/dimens.xml" to="${escapeXmlAttribute(resOut)}/values/dimens.xml"/>
<merge from="res/values/strings.xml.ftl" to="${escapeXmlAttribute(resOut)}/values/strings.xml" />
複製程式碼
14.工程建立成功後開啟對應檔案
<open file="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java" />
<open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />
複製程式碼

如果你的Android Studio IDE執行,請重新啟動它看到自己的模板如下圖

【譯】移動應用開發:如何建立自定義Android程式碼模板
如果從模板生成專案時遇到此錯誤:AssertionError: Wrong line separators: ‘…plication;\r\n\r\nimport…’ at offset 29: 請檢查模板中所有檔案的行分隔符是否正確,請確保使用正確的行分隔符在對應的的計算機的作業系統中。

原文連結

相關文章