由于我的项目是MVP分层架构的,其实分层架构本身是一个好事,结构清晰,代码的健壮性强,但是每次创建页面都需要生成四五个类,页面一多,就要重复非常多次,这样的效率太低了,那有没有什么办法可以一次性,将样板代码生成好呢?
答案当然是有的,注意过么,每次我们通过AndroidStudio创建一个新Activity的时候,是会生成完整Activity模板代码的,那么我们是否可以自定义这个行为呢?
可以的!方法如下:
首先进入到AndroidStudio软件目录下android-studio\plugins\android\lib\templates\activities\
,这里面可以看到很多熟悉的名字,这就是平时使用的模板的存放位置。
在这里可以建立一个模板文件夹,举例为MVPActivity
。也可以复制一个模板以此为基础修改。
template_blank_activity.png
这张图片是展示在生成对话框左侧的图片,可以自定义为任何自己喜欢的图片。
template.xml
这个是模板生成菜单的参数配置,可以在这里定义自己需要的参数,这里面的参数会作为后面生成模板的参数。参数的内容其实比较好理解。
- id:用户输入的参数,相当于变量名
- name:在生成页面里显示的Label名称
- type:类型
- constraints:约束,包括是否非空等
- default:默认值
- help;该参数对应的提示信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <?xml version="1.0"?> <template format="5" revision="5" name="MVP Activity" minApi="9" minBuildApi="14" description="Creates a new MVP activity">
<category value="Activity" /> <formfactor value="Mobile" />
<parameter id="className" name="Class Name" type="string" constraints="nonempty" default="Item" help="Your MVP basic name." /> <parameter id="classDesc" name="Class Desc" type="string" constraints="nonempty" default=" " help="Desc your class" />
<parameter id="packageName" name="Package name" type="string" constraints="package" default="com.mycompany.myapp" />
<thumbs> <thumb>template_blank_activity.png</thumb> </thumbs>
<globals file="globals.xml.ftl" /> <execute file="recipe.xml.ftl" />
</template>
|
recipe.xml.ftl
这个是最终需要生成的文件的列表。include里面的是生成Activity对应在AndroidManifest.xml中的条目。如果不需要自动生成,也可以将此行注释掉。
如果需要生成layout文件的话,也可以在这里添加,推荐参考EmptyActivity
的模板格式。
没有出现在这里的参数,简单描述一下:
- copy:从root中复制文件到目标目录,这里是直接复制的操作。
- merge:合并,比如将使用到的strings.xml合并到项目的stirngs.xml中。
- instantiate:讲ftl文件按照规则转义后,生成到对应文件夹中,类似copy。
- open:在代码生成后,打开指定的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0"?> <recipe> <#include "../common/recipe_manifest.xml.ftl" /> <instantiate from="root/src/app_package/EmptyActivity.java.ftl" to="${escapeXmlAttribute(srcOut)}/${ActivityName}.java" /> <instantiate from="root/src/app_package/EmptyFragment.java.ftl" to="${escapeXmlAttribute(srcOut)}/${FragmentName}.java" /> <instantiate from="root/src/app_package/EmptyPresenter.java.ftl" to="${escapeXmlAttribute(srcOut)}/${PresenterName}.java" /> <instantiate from="root/src/app_package/EmptyView.java.ftl" to="${escapeXmlAttribute(srcOut)}/${ViewName}.java" /> </recipe>
|
globals.xml.ftl
这里面是id和参数的定义文件,可以理解为变量存放的位置,便于后面ftl文件使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?xml version="1.0"?> <globals> <#assign Collection=extractLetters(className)> <#assign ClassDesc=extractLetters(classDesc)> <global id="ActivityName" value="${Collection}Activity" /> <global id="FragmentName" value="${Collection}Fragment" /> <global id="PresenterName" value="${Collection}Presenter" /> <global id="ViewName" value="${Collection}View" />
<global id="DescContent" value="${ClassDesc}" />
<global id="activityClass" value="${Collection}Activity"/> <global id="isLauncher" type="boolean" value="false" />
<#assign collection_name=Collection?lower_case> <global id="activity_layout" value="${Collection?lower_case}" /> <global id="fragment_layout" value="${Collection?lower_case}" /> <global id="hasNoActionBar" type="boolean" value="false" /> <global id="parentActivityClass" value="" /> <global id="excludeMenu" type="boolean" value="true" /> <global id="generateActivityTitle" type="boolean" value="false" /> <#include "../common/common_globals.xml.ftl" /> </globals>
|
接下来的就可以在对应的目录下添加模板的ftl文件来设置生成模板代码的类型。
这里以EmptyActivity.java.ftl
作为例子,其余的大同小异,也可以查阅FreeMarker的语法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package ${packageName};
import ${superClassFqcn}; import android.os.Bundle;
public class ${activityClass} extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
|
如果遇到修改后无法生成代码的问题也不要慌,AndroidStudio右下角会出现一个红色的叹号,这里面出现的都是AndroidStudio运行时遇到的异常,在这里就可以看到,为什么模板没有成功生成的原因了。
节省的时间,就可以做更有意义的事情了。
参考: