【Android】もっと先へ「加速」したくはないか、少年 〜Project Template編〜

  • 147
    Like
  • 0
    Comment
More than 1 year has passed since last update.

今回は新規プロジェクトを作成する際に、毎回同じパッケージ構成をしている、毎回同じファイル作ってるという方向けの投稿です。

少しだけ裏技チックな手法を使います。

前置き

github上で最近★を集めていてAndroidのベストプラクティスについ触れているandroid-best-practices をご存知でしょうか?

ここではpackage構成は下記が良いと言っています。

com.futurice.project
├─ network
├─ models
├─ managers
├─ utils
├─ fragments
└─ views
   ├─ adapters
   ├─ actionbar
   ├─ widgets
   └─ notifications

私はこれに少しカスタマイズしたものを採用しております。

少しだけ説明すると、MVC + 3層レイヤーをAndroidで構築すると下記のようになるという考えを持っているので、

これに基づいて、package構成は下記のようにしています。

com.kugimiya.project
├─ network
├─ models
|  ├─ entities
|  ├─ prefs
|  ├─ apis
|  └─ provider
├─ utils
├─ fragments
├─ services
└─ views

加えてプロジェクトを新規で作るとほぼほぼSettingのPreferenceを作るので、新規プロジェクト作成時には毎回下記のようなところまでやって組み始めてました。

com.kugimiya.project
├─ network
├─ models
|  ├─ SettingModel.java
|  ├─ entities
|  |   └─ Setting.java
|  ├─ prefs
|  |   └─ SettingPrefs.java
|  ├─ apis
|  └─ provider
├─ utils
├─ fragments
├─ services
└─ views

毎回やってるなら自動化したい。そういう思いでいろいろ探したり試行錯誤していると見つけました。

Project Templateを使います。

Project Templateとは

Project Templateという言葉自体は勝手に僕がつけた造語です。
その名の通りProjectのTemplateです。

Project Templateの作り方

Macの方への説明になってしまいますが、Windowsの方も似たような方法で行けると思います。

まず、「Android Studio.app」を右クリックして「パッケージの内容を表示」を選択します。

中を開いて「plugins」-> 「android」->「lib」->「templates」->「activities」と潜っていくとここにどこかで見慣れたTemplate一覧があります。

ここにTemplateを追加する事で下記のように自作のTemplateが表示されます。(下記の場合は Blank Activity Kugimiya がそれです。)

ではTemplateの作り方を説明します。
ベースとなるTemplateをコピーして適当にリネームします。
下記では「BlankActivityKugimiya」がそれです。

今回は、root/src/app_package配下とrecipe.xml.ftlのみ触ります。
まず、app_package 配下を下記のような構成にします。

app_package
├─ models
|  ├─ SettingModel.java.ftl
|  ├─ package-info-models.java.ftl
|  ├─ entities
|  |   ├─ Setting.java.ftl
|  |   └─ package-info-entities.java.ftl
|  ├─ prefs
|  |   ├─ SettingPrefs.java.ftl
|  |   └─ package-info-prefs.java.ftl
|  ├─ apis
|  |   └─ package-info-apis.java.ftl
|  └─ provider
|      └─ package-info-provider.java.ftl
├─ utils
|   └─ package-info-utils.java.ftl
├─ fragments
|   └─ package-info-fragments.java.ftl
├─ services
|   └─ package-info-services.java.ftl
└─ views
    └─ package-info-views.java.ftl

生成したいものはファイル名の最後に「.ftl」を付け加えて、「${packageName}」でapp_packageまでのパッケージ名を取得できるので、つじつまが合うように書きます。

例えば、Setting.java.ftlは

Setting.java.ftl
package ${packageName}.models.entities;

/**
 * Setting Entity
 * @author Kugimiya
 */
public class Setting {
}

となり、package-info-models.java.ftlは下記のようになります。

/**
 * Models.
 * @author Kugimiya
 */
package ${packageName}.models;

(ちなみになぜpackage-info.java.ftlでなくpackage-info-models.java.ftlなどとなっているかというと、名前が被ると全て最初に認識されたものが生成されてしまうからです。)

次に、recipe.xml.ftlを修正します。といっても<!-- ここから --> から <!-- ここまで --> の部分を挿入するだけです。


<?xml version="1.0"?>
<recipe>

    <#if appCompat><dependency mavenUrl="com.android.support:appcompat-v7:${targetApi}.+"/></#if>

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

    <instantiate from="res/menu/main.xml.ftl"
            to="${escapeXmlAttribute(resOut)}/menu/${menuName}.xml" />

    <merge from="res/values/strings.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/strings.xml" />

    <merge from="res/values/dimens.xml.ftl"
             to="${escapeXmlAttribute(resOut)}/values/dimens.xml" />
    <merge from="res/values-w820dp/dimens.xml"
             to="${escapeXmlAttribute(resOut)}/values-w820dp/dimens.xml" />

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

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

    <!-- ここから -->

    <instantiate from="src/app_package/models/package-info-models.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/package-info.java" />
    <instantiate from="src/app_package/models/entities/package-info-entities.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/entities/package-info.java" />
    <instantiate from="src/app_package/models/prefs/package-info-prefs.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/prefs/package-info.java" />
    <instantiate from="src/app_package/models/provider/package-info-provider.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/provider/package-info-provider.java" />
    <instantiate from="src/app_package/utils/package-info-utils.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/utils/package-info.java" />
    <instantiate from="src/app_package/services/package-info-services.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/services/package-info.java" />
    <instantiate from="src/app_package/fragments/package-info-fragments.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/fragments/package-info.java" />
    <instantiate from="src/app_packag/package-info.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/package-info.java" />

    <instantiate from="src/app_package/models/entities/Setting.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/entities/Setting.java" />
    <instantiate from="src/app_package/models/prefs/SettingPrefs.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/prefs/SettingPrefs.java" />
    <instantiate from="src/app_package/models/SettingModel.java.ftl"
                   to="${escapeXmlAttribute(srcOut)}/models/SettingModel.java" />

    <!-- ここまで -->

    <open file="${escapeXmlAttribute(srcOut)}/${activityClass}.java" />
    <open file="${escapeXmlAttribute(resOut)}/layout/${layoutName}.xml" />

</recipe>


以上で完了です!

早速新規プロジェクトを立ち上げ自作のテンプレートを生成してみると、しっかり生成されている事が確認できます。

まとめ

アプリを量産したい方、自分自身のフレームワークが固まっている方、固めたい人は作るべきだと思います。
Project Templateを作って、開発効率を上げましょう!

バーストリンカーなら合わせて読みたい

【Android】もっと先へ「加速」したくはないか、少年 〜File Template編〜