【译】移动应用开发:如何创建自定义Android代码模板
介绍
这篇教程会为你展示如何创建属于你自己的代码模板。大多数的Android开发者都至少一次使用过Android代码模板来新建工程。但是你有没有尝试过创建自己的Android代码模板?在这篇教程中,我们将会为你展示可用于从Android Studio IDE生成包含Google Analytics配置的Android工程模板。
源码
在这里下载源码原文链接
代码生成过程图解
具体创建步骤
要创建自己的模板,请确保:
- 你已经了解上述代码生成过程图解;
- 你有一些关于FreeMarker的知识;
- 你有一些关于Android IDE模板格式的知识,你可以在这里查看相关文档。
第一步:创建Google Analytics应用程序文件夹
这是你的模板目录,在Windows上,${android studio 安装路径}/plugins/android/lib/templates/,其他平台Linux,Mac OS请自行查找;在GoogleAnalyticApplication文件夹中创建根文件夹和其他文件,如下所示:
第二步:创建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,将在创建项目时显示在弹出窗口中。
第三步:创建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文件夹中包含模板源代码
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.检查依赖
9.检查AndroidManifest.xml.ftl
<instantiate from="AndroidManifest.xml.ftl" to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" />
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#
11.检查MainActivity.java.ftl
<instantiate from="src/app_package/activities/MainActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/activities/${activityClass}.java"/>
12.检查analytics_global_config.xml.ftl
<instantiate from="res/xml/analytics_global_config.xml.ftl" to="${escapeXmlAttribute(resOut)}/xml/analytics_global_config.xml"/>
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运行,请重新启动它看到自己的模板如下图
如果从模板生成项目时遇到此错误:AssertionError: Wrong line separators: ‘…plication;\r\n\r\nimport…’ at offset 29:请检查模板中所有文件的行分隔符是否正确,请确保使用正确的行分隔符在对应的的计算机的操作系统中。原文链接