EclipseでのAndroid開発でドメインの実装を別プロジェクトに分離する

[JUnit 実践入門](http://www.amazon.co.jp/JUnit%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-~%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E6%8A%80%E6%B3%95-WEB-PRESS-plus/dp/477415377X) で、ドメインロジック（モデル）は Android プロジェクトとは分離して、普通の Java プロジェクトとして作成するのが良いと紹介されている。

その通りだと思うが、紹介されている方法だと問題点が１つある。
それは、ドメイン側の実装を変更したら都度ビルドを実行する必要があるという点。正直面倒です。。。

なんとかならんかと試行錯誤した結果、それっぽくできたのでメモ。

#目標
- Android の UI とかを作るプロジェクト（以後、 UI プロジェクト）と、ドメインロジックを実装するプロジェクト（以後、ドメインプロジェクト）を分離する。
- ドメインプロジェクトは、ただの Java プロジェクト。
- ドメインプロジェクトを修正したら、面倒な手順なしに UI プロジェクトにも変更が反映される。
- そのままエミュレータ上で動かせる。
- Gradle でビルドできる。

#方法
「ソースのリンク」を使って、 UI プロジェクトにドメインプロジェクトのソースフォルダを追加する。

build.gradle は ADT の機能で出力してから、マルチプロジェクト化させる。

#手順
##ドメインプロジェクト
普通に Gradle で Eclipse プロジェクトを作る。

```groovy:build.gradle
apply plugin: 'java'

// 本当は 1.6 がいいんだろうけど、とりあえず動くので 1.7 で
sourceCompatibility = '1.7'
targetCompatibility = '1.7'

apply plugin: 'eclipse'

eclipse {
    project {
        name = 'Domain'
    }
}
```

```text:フォルダ構成
|-build.gradle
`-src/main/java/sample/domain/
  `-MyDomain.java
```

```java:MyDomain.java
package sample.domain;

public class MyDomain {
    
    public String method() {
        return "MyDomain!!";
    }
}
```

##UI プロジェクト
###プロジェクトを作成する
まずは、普通に Android プロジェクトを作る。

ドメインプロジェクトとの位置関係は以下のようになるよう作成する。

```text:
|-Domain/
`-UIProject/
```

###ソースのリンクを作成する
次に、「ソースのリンク」を作成する。
ビルド・パスの構成を開き、「ソース」タブの「ソースのリンク」をクリック。

リンクするソースの設定を入力する。

![android.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/344df15c-140b-483d-3a50-f9fdf5b8b1ae.jpeg)

ここで使用している `DOMAIN_LOC` は新規に追加したパス変数で、ドメインプロジェクトを指すように設定している。
パス変数の設定は、同画面の「変数」から可能。

![android.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/12c94053-b6a3-8e21-883a-2cd5bf27e9e2.jpeg)

「新規」をクリックし、以下のように `PROJECT_LOC` を基準に設定している。

![android.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/dd0ecbbf-4571-8601-95a0-c32d4325b510.jpeg)

リンクができあがると、以下のような感じになる。

![android.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/9824aa93-e14e-85a6-67cd-57aa38e6961d.jpeg)

##build.gradle を作る
###UI プロジェクトの build.gradle を出力する
UI プロジェクトを右クリックして、「エクスポート」→「Android」→「Generate Gradle build files」を選択する。

あとは、ダイアログの指示に従って UI プロジェクトを選択して build.gradle を出力する。

```groovy:出力されたbuild.gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.12.+'
    }
}
apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
}

android {
    compileSdkVersion 18
    buildToolsVersion "20.0.0"

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src','domain_src']
            resources.srcDirs = ['src','domain_src']
            aidl.srcDirs = ['src','domain_src']
            renderscript.srcDirs = ['src','domain_src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}
```

###マルチプロジェクトにする
UI プロジェクトの１つ上のフォルダに移って、 settings.gradle を作る。

```groovy:settings.gradle
include ':UIProject'
include ':Domain'
```

```text:フォルダ構成
|-settings.gradle
|-Domain/
`-UIProject/
```

UI プロジェクトの build.gradle の dependencies にドメインプロジェクトを追加する。

```groovy:UIプロジェクトのbuild.gradle
dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':Domain')
}
```

以上で、 `gradle build` すればビルドが実行できるようになった。

一応 Eclipse からエミュレータで動かせることは確認したけど、実機では確認していない。
gradle が吐いた apk も実機では試してないけどきっと大丈夫と信じたい（正直ライブラリの依存管理ができたら十分かなとも思う気もしなくはない）。