打造更好用的 Android Studio:添加 Templates 以及改造 gradle-projects

<b>对模板工程的改造有可能造成 Android Studio 更新失败!</b>*

最近我从 1.5 -> 1.5.1 更新失败,就是对模板工程的改造造成了冲突!
<p>

中午 @drakeet 秀了一波他改造的两个小模板,另外还发了几张官方自带模板的本地位置图片,我也跟着改造了一把。

添加自定义 Templates

自定义的位置入口在这儿:

edit.png

然后,选择 Templates 按 + 就可以一步步操作啦。

templates.png

Description 处有些很有用的说明,这里指出了多个占位符号,可以在根据模板类生成具体的类时替换成合适的字符。

  • 静态内部类实现的单例。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME}{
    public static ${NAME} getInstance() {
        return ${NAME}Holder.sInstance;
    }

    private ${NAME}() {
    }

    private static class ${NAME}Holder {
        private static final ${NAME} sInstance = new ${NAME}();
    }
}
  • BaseAdapter,引入 provideItemLayout() 方法是为了解决 R 文件引入的包名问题,ViewHolder.bind(Object) 可以将 UI 和数据绑定放在一起。
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.List;

#parse("File Header.java")
public class ${NAME} extends BaseAdapter {

    private Context ctx;
    private List<Object> objects;

    public ${NAME}(Context ctx, List<Object> objects) {
        this.ctx = ctx;
        this.objects = objects;
    }

    private @LayoutRes int provideItemLayout() {
        // todo
        return 0;
    }

    @Override
    public int getCount() {
        return objects == null ? 0 : objects.size();
    }

    @Override
    public Object getItem(int position) {
        return objects.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        
        if (convertView == null) {
            convertView = LayoutInflater.from(ctx).inflate(provideItemLayout(), parent, false);
            
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        
        holder.bind(objects.get(position));
        
        return convertView;
    }

    public static class ViewHolder {
        
        public ViewHolder(View convertView) {
            // todo
        }
        
        public void bind(Object o) {
            // todo
        }
    }
}
  • RecyclerView Adapter
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

#parse("File Header.java")
public class ${NAME} extends RecyclerView.Adapter<${NAME}.ViewHolder>  {

    private Context ctx;
    private List<Object> objects;

    public ${NAME}(Context ctx, List<Object> objects) {
        this.ctx = ctx;
        this.objects = objects;
    }

    private
    @LayoutRes
    int provideItemLayout() {
        // todo
        return 0;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(ctx).inflate(provideItemLayout(), parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.bind(objects.get(position));
    }

    @Override
    public int getItemCount() {
        return objects == null ? 0 : objects.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(View itemView) {
            super(itemView);
            //todo
        }

        public void bind(Object o) {
            // todo
        }
    }
}

改造 gradle-projects

在添加了几个自定义的 Templates 之后,我想能不能去改造一下整个 project,让它自动帮我们创建更多的文件、配置更多的内容。

我曾经想改造一下,但是没有 Google 到方法,然后我创建了一个工程,把必须要的依赖啊、包啊、类啊都配置好,想要以后再新建工程时直接 copy 一份然后修改包名就行了,后来我发现改包名太累,放弃了。

以下就是手术过程。

找到模板工程位置:

AndroidStudio\plugins\android\lib\templates\gradle-projects

这个下面有多个文件夹,一看名字就知道是干啥的。

projects.png

改造前请先备份!

改造前请先备份!

改造前请先备份!

</p>

先看 NewAndroidProject 有什么可以改造的没有

研究了一下这个目录下的文件,我发现最重要的是recipe.xml.ftl 这个文件,它描述了工程创建过程应该做些什么,copy 操作是简单的复制,instantiate 操作是实例化,AS 除了生成一些变量替换掉占位符,还会插入一些内容。globals.xml.ftl 则定义了一些常量。据此,我们可以修改的文件是
NewAndroidProject\root\project_ignoreNewAndroidProject\root\local.properties.ftl,前者是整个工程的 ignore 文件,可以在 https://www.gitignore.io 生成一份拷贝进去,后者我们可以定义一些密码之类的(要确保该文件不会加入版本控制系统)。

接下来看看 NewAndroidModule 有什么可以改造的没有

根据前面的经验,先研究一下 recipe.xml.ftl 这个文件,有以下发现:

  1. 第 4 行的 dependency 定义 appcompat-v7
  2. 第 14 行实例化了 build.gradle
  3. 第 19 行创建了 drawable 文件夹
  4. 第 33 行拷贝了 module 的 ignore
  5. 第 37 行生成了 proguard 文件
  6. 第 55 行生成了 res/value/strings.xml

继续研究 NewAndroidModule\root 下的文件。

  1. build.gradle.ftl 是 module 的 build.gradle 模板,我想提前做点配置进去。我比较疑惑的是第 65 行的 <#if dependencyList?? > ,这里看起来是某个地方定义了一个依赖列表,但是并没有发现。回过头去看 recipe.xml.ftl ,它的第 4 行是 <dependency mavenUrl="com.android.support:appcompat-v7:${buildApi}.+"/> ,我猜测可能这就是定义的地方,于是在这后面仿写了一句 <dependency mavenUrl="com.jakewharton:butterknife:7.0.1"/> ,创建工程验证确实如我所猜测的那样。
  2. module_ignore 最简单,根据我们的需要再添加一些语句就行
  3. proguard-rules.txt.ftl 会被实例化到 proguard-rules.pro,可以根据对 build.gradle.ftl 的修改适当修改

还可以继续改造的是:自动生成一些包,让程序架构更清晰,先把架子搭起来嘛。

参考资料

  1. File and Code Templates
  2. 使用FreeMarker模板引擎自定义Android工程模板
  3. AndroidStudioTemplate
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 由于项目用上了 mvp 架构,基本上一个页面就至少需要新创建6个类,分别是 model view presente...
    大空ts翼阅读 1,953评论 0 4
  • 1 背景 一个项目开发必然会涉及团队协作,而工程质量就需要团队去保证。一般我们期望的代码:无潜在风险、无重复逻辑、...
    zyl06阅读 3,210评论 5 16
  • 视频链接 0 背景 我们网易前端技术部 - 移动技术组作为公司的移动端基础技术部门,主要为其他部门提供解决方案、技...
    zyl06阅读 2,514评论 0 17
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,732评论 6 342
  • 后面又看到关于朱元璋的章节,很多都是怎么打战的。 比较精彩的部分是那里有很多出其不意的猛将,朱元璋的侄子朱文正守一...
    Molly_0阅读 99评论 0 0