EclipseからAndroid Studio移行ではまったところメモ

最近、Android Studioに乗り換えました。Gradleが面白いです。
でもEclipseから移行するときにかなりはまりました。はまったところをメモしておきます。

#前提条件

環境によって使えないパラメータなどが存在しているため、環境は以下になります。

Android Studio v0.8.2
Gradle v1.12（Android Studioに付属しているpluginを利用）

#外部ファイルから読み込む

開発時にチームメンバー毎に見ているサーバが違ったりします。
その対応をするために、プロジェクト外部からデータを読み込む方法。


```properties:other.properties
ext.prop1="test"
```

```groovy:app/build.gradle
apply plugin: 'com.android.application'

android {
    buildTypes {
        debug {
            println "debug"
            apply from: "${System.properties['user.home']}/other.properties"
            println project.prop1
        }
    }
...
}
```

結果

```
debug
test
```

ちなみに普通にpropertiesとして読み込むこともできる。Gradleのバージョン次第ではこちら？を使うべきなのかな？

```groovy:app/build.gradle
apply plugin: 'com.android.application'

android {
    buildTypes {
        debug {
            Properties props = new Properties()
            props.load(new FileInputStream("${System.properties['user.home']}/other.properties"))
            println props.getProperty("ext.prop1")
        }
    }
...
}
```

# Gradleで設定した値をJavaファイルで利用できるようにする。

上のデータをJavaでも利用したい場合とかに便利

```groovy:app/build.gradle
android {
    buildTypes {
        debug {
            apply from: "${System.properties['user.home']}/other.properties"
            buildConfigField 'String', 'FOO', 'BAR'
            buildConfigField 'String', 'PROP1', "\"$project.prop1\""
        }
    }
...
}
```

```java:BuildConfig
public final class BuildConfig {
...
  public static final String FOO = "BAR";
  public static final String PROP1 = "test";
...
}
```

このBuildConfigは自動で生成されるものなので、手を出さないこと。
この場合、BuildConfig.FOO/BuildConfig.PROP1でアクセスできる、static initializerでも利用可。
ただし、上記コードはdebugのみで作っているため、releaseなどのvariantに変更した場合、コンパイルエラーを起こす。
利用するときはbuildTypeなどで分けたdebugでしか使わないコードでのみ利用すること。

# ライブラリプロジェクトのライブラリについて

そもそもが複雑なのだけど、例えば、3rdパーティライブラリをラッピングして使いやすくすることがちょくちょくある。
例として、
3rdパーティライブラリとしてVolley
Volleyを使っているプロジェクトA
VolleyをラッピングしたライブラリをB

とすると、構成が以下のようになる。

```
A
├── app
├── settings.gradle
└── libraries
  ├── Volley
  └── B
    └── Volley
```

実際細かい動きまで把握していないのだけど、重複されているのは良きに計らってくれるという話を聞いてはいますが、重複はよろしくない。

```
include ':libraries:volley'
```

と記載してあれば、Bのライブラリでも利用できるため、Bでvolleyをimportする必要がなくなる。
また、Bにはsettings.gradleを含めないようにする。（BをAndroid Studio用にimportするとsettings.gradleもこのライブラリも含まれるので注意。）
こういうこと考えだすと、フラット構成のほうがいいのでは？と思ったりします。。。
どうせほとんどがgradleで管理することになるんだし。その辺りは検討すること。

# buildTypeでクラスを分ける

ちまたでちょくちょく見かける、buildtypeをさっそくつかうとDuplicate class foundと怒られる。

```
.
├── debug
│   └── java
│       └── com
│           └── myapplication
│               └── MyActivity.java
├── main
│   ├── AndroidManifest.xml
│   ├── java
│   │   └── com
│   │       └── myapplication
│   │           └── MyActivity.java
│   └── res
└── release
    └── java
        └── com
            └── myapplication
                └── MyActivity.java
```

まぁ当然ちゃー当然なのだけど。
buildtypeでクラスを分ける場合は同じパッケージのmainにあるファイルを取り除くこと。
あと、buildtype/java/package/構成であることもチェックしておくこと。javaフォルダを結構忘れがち。

関係ないけど、Android StudioのBuild Variantsでdebugを選択すると、releaseのjavaフォルダが普通のフォルダとして認識される。debugのjavaフォルダはjavaソースフォルダとして認識されている。

# SDK managerの使い方。

Jake Whartonさんの[sdk-manager-plugin](https://github.com/JakeWharton/sdk-manager-plugin)の利用方法。

```groovy:build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.12.+'
        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
    }
}
```
```groovy:app/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'android'
...
```
としたら動いた。

サブモジュールとして追加したbuild.gradleにも以下のコード入れる必要あり。
基本、app/build.gradleに書けば問題ない。

```groovy:submoduleのbuild.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
```

# ライブラリの追加方法

基本、MavenCentral（jcentral）にあれば、それを利用する。無理して複雑なことをしようとしない。

volleyをsubmoduleとして追加すると、sdk-manager動かないわ、support-libraryで涙目になるわで大変。
[mcxiaoke/android-volley](https://github.com/mcxiaoke/android-volley)これ使えば何も考えなくて済む問題が何日も考えなくはならなくなる。
自作でMavenレポジトリを作るとかでもできそう。（そこまでする必要があればだけど・・・）


#プロジェクトのimport手順

EclipseのADTプラグインでは以下の手順でGradleファイルを作成すると色々な場所で記載されている。

```
Export > Android > Generate Gradle build files
```

これを使うとプロジェクト作成に時間がかかる。

Android Studioのimport機能から直接Eclipseのプロジェクトをimportするほうが早くて正確。


とりあえず、Eclipseからの移行で発生した問題を羅列してみた。
簡単にいくはずだったんだけどな・・・。でもGradleが便利すぎて助かります。

---

ここから、後に発生した問題

#ログコードをproguard時に削除する

Eclipseでログコードをproguard時に削除していた。

随所にコードが散らばっているので今頃といえば今頃だけど、削除するコードはこんな感じ。

```
#-dontoptimize

-assumenosideeffects class android.util.Log {
    public static int v(...);
    public static int d(...);
    public static int i(...);
    public static int w(...);
    public static int e(...);
}

// カスタムロッガーの場合は全部消してしまう。
-assumenosideeffects class com.shiraji.Logger {
    <methods>;
}
```

で、それをEclipseではやっていたのだけど、いざ、Android Studioでやってみたら、ログが出力されてた。
デコンパイルしてソースみたらきっちりソース残ってた。

/Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt

ここにproguard-android.txtが存在していて、そこにはproguard-android-optimize.txtを使えという指示がある。
色々探しても使えばいいとだけしか記載されていなくて、どう使うのこれ？ってはまりました。

移行した直後ではこんな記載になっていました。

```groovy:app/build.gradle
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
```

getDefaultProguardFileの指定をproguard-android-optimize.txtに切り替えれば良いみたいです。

```groovy:app/build.gradle
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
```

このデフォルトで指定された項目にないものをその次のパラメータで渡しているファイルに記載するのが普通みたいです。プロジェクト毎の指定をするためのものです。
問題にはならないのだけど、結構重複していたので、移行時に綺麗にしたほうがよいです。

そもそもEclipseのときのproguardの使い方が間違っていたのでは？という感じですが・・・。

#Save Actions（保管アクション）がない

Android Studioには保管アクションがない。
Eclipseだと、cmd + sで同時にコードフォーマットをかけていたのだけど、それができない。[ADT(Eclipse)の環境構築メモ - 保管アクション](http://qiita.com/shiraji/items/9cb3b0fd1169063b7db9#1-11)を参照。
これを行うためには、Edit > Macros > Start Macro Recordingsからマクロを記録させ、

1. Code > Optimize imports...
1. Code > Reformat codes...
1. File > Save all

でマクロを任意の名前で登録する。
その後、Keybindの設定でcmd + sをアンバインドし、上記のmacroをcmd + sにバインドする必要がある。

## 追記

便利なライブラリがあるので、そちらの利用もおすすめです。
Save Actions
https://plugins.jetbrains.com/plugin/7642

#Eclipse Code Formatterでimport文位置が不安定になる

上記の設定をするとEclipseのようなコードフォーマットになる。
しかし、import文がcom系が上だったり、java系が上だったりと挙動がかなり不安定になる。

Preferences > Eclipse Code Formatterの真ん中あたりの設定にOptimize Importsがチェックされている場合は外す必要がある。
この設定と上記のOptimize imports/Reformat codesが競合してしまう模様。

#xmlのフォーマットが崩れる。

Eclipse Code Formatterを設定し、Code Styleを変更するとxmlのフォーマットがEclipse Code Formatter用になる。
ed