Android版ネイルブックで利用しているオススメのライブラリ１０選！


これは [スピカ Advent Calendar 2015](http://qiita.com/advent-calendar/2015/spika) の２２日目の投稿です。（といいつつ、投稿が遅れてすみせん..）

私は [Android版ネイルブック](https://play.google.com/store/apps/details?id=jp.nailbook) の開発に携わっています。ネイルブックでは [iOS版](https://itunes.apple.com/jp/app/id432831907) と合わせて **毎日２０００枚以上** もの新しいネイル画像が投稿され、累計で投稿されたネイル画像は **１００万枚** を超えます。

![movie3.gif](https://qiita-image-store.s3.amazonaws.com/0/35733/55181808-6039-9e78-55c5-0c963fbfb6e5.gif "movie3.gif") ![movie1.gif](https://qiita-image-store.s3.amazonaws.com/0/35733/a98b8e9d-c3c3-9b57-30a1-e6e173568c46.gif "movie1.gif") 

Android 版については、つい先日(12/25)にバージョン `2.0.0` がリリースされました（上のキャプチャは少し古いバージョンのものですが）。このバージョンアップでデザイン＆操作性ともに大きく向上し、画像閲覧系アプリとして良い参考になるかと思います。是非ダウンロードして試していただければ。

今回は [Android版ネイルブック](https://play.google.com/store/apps/details?id=jp.nailbook) で利用しているライブラリの中から、便利に使っているものを厳選して１０個、紹介したいと思います！

## ① Picasso

![スクリーンショット 2015-12-25 18.11.03.png](https://qiita-image-store.s3.amazonaws.com/0/35733/90027bbd-3baa-7b61-9a7a-44787b5cadb8.png "スクリーンショット 2015-12-25 18.11.03.png")
> サイト：http://square.github.io/picasso/

ネイル画像はサーバ側からは Amazon CloudFront で配信し、アプリからの読み込みには Picasso を利用しています。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.squareup.picasso:picasso:2.5.2'
}
```

Picasso を利用する場合は、あわせて [OkHttp](http://square.github.io/okhttp/) を導入しておくと、特に何も設定せずともネットワーク接続に OkHttp を利用してくれるようになります。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.squareup.okhttp:okhttp:2.5.0'
}
```

基本的な使い方は Picasso のサイトを見てたりググッてもらえれば分かると思います。ネイルブックでは画像を読み込み終わったら◯◯する、という処理がわりとあるのですが、次のようなコールバックも簡単に書けて便利です。

```java:
Picasso.with(someImageView.getContext().getApplicationContext())
        .load(image_url_string)
        .placeholder(R.drawable.loading_image)
        .error(R.drawable.error_image)
        .into(someImageView, new Callback() {
            @Override
            public void onSuccess() {
                // 画像を読み込み終わった時に実行する処理
            }
            @Override
            public void onError() {
                // エラーの時に実行する処理
            }
        });
```

Transformation で画像の加工もできます。例えば [画像を円でくり抜くTransformation](https://gist.github.com/julianshen/5829333) があるとしたら、次のように利用します。

```diff:
Picasso.with(someImageView.getContext().getApplicationContext())
        .load(image_url_string)
+        .transform(new CircleTransformation()) // 円でくり抜く
        .placeholder(R.drawable.loading_image)
        .error(R.drawable.error_image)
        .into(someImageView);
```

Transformation は独自で作成する他に、私はまだ利用したことが無いのですが wasabeef さんが開発されている [Picasso Transformations](https://github.com/wasabeef/picasso-transformations) などがあります。

また Picasso のは読み込んだ画像がネットワークから新たに読み込まれたのか / データストアのキャッシュからなのか / メモリからなのかを、画像の左上に赤 / 青 / 緑 のマークをつけて教えてくれる機能(インジケータ表示)があります。

![スクリーンショット 2015-12-26 1.36.53.png](https://qiita-image-store.s3.amazonaws.com/0/35733/f7e5c556-7933-da80-a5b9-9b2e5f002385.png "スクリーンショット 2015-12-26 1.36.53.png")

利用するには Application クラス等で次のようにします。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.DEBUG) {
            Picasso.with(getApplicationContext()).setIndicatorsEnabled(true);
        }
    }
}
```

次のように Picasso が利用するメモリの容量(デフォルトでは端末で利用できる容量の約15%)を変更することも出来ます。

- [Picasso が利用するメモリのサイズを変更する](http://qiita.com/hkusu/items/1db498f1e9475a2472ef)

## ② Stetho

![2d6b9c51-fffc-9516-4459-68dbccbe631d.png](https://qiita-image-store.s3.amazonaws.com/0/35733/8fa103f3-8d4e-1bda-e3f1-6552ac645fdf.png "2d6b9c51-fffc-9516-4459-68dbccbe631d.png")
> サイト：http://facebook.github.io/stetho/

`SharedPreferences` の中身を Chrome Developer Tools で確認するのに利用しています。

```:build.gradle：プロジェクトへの導入
dependencies { 
    debugCompile 'com.facebook.stetho:stetho:1.2.0'
}
```
> ネイルブックでは debug ビルド時のみしかバイナリに組み込まれないよう `debugCompile` で定義しています。

利用するには Application クラス等で次のように初期化するだけです。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Stetho.initializeWithDefaults(this);
    }
}
```
> ネイルブックでは relese / debug ビルドで Application クラスのソースを分けています。もし分けないなら `build.gradle` の `compile` で Stetho を読み込み、`BuildConfig.DEBUG == true` の場合に Stetho を初期化する、とすると debug ビルド時のみ Stetho が有効となる状態が作れます。

上記のように初期化しておくと、Chrome Developer Tools で inspect できるようになります。

![スクリーンショット 2015-12-26 1.29.23.png](https://qiita-image-store.s3.amazonaws.com/0/35733/ddc2b6e3-c261-fe64-f187-eb641d011f8b.png "スクリーンショット 2015-12-26 1.29.23.png")

次のように `SharedPreferences` の中身が確認できます。（あまり見せれないのでモザイクかけてますが..）

![スクリーンショット_2015-12-26_1_33_46.png](https://qiita-image-store.s3.amazonaws.com/0/35733/ff67bbb5-d2df-b6b1-7c7a-46432c4cb223.png "スクリーンショット_2015-12-26_1_33_46.png")

ネイルブックでは画像の読み込みに、先に紹介した Picasso(とOkHttp) を利用しているのですが、Stetho-OkHttp を導入することにより、画像のHTTPリクエストも Chrome Developer Tools で確認できるようになります。

```:build.gradle：プロジェクトへの導入
dependencies { 
    debugCompile 'com.facebook.stetho:stetho-okhttp:1.2.0'
}
```

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Stetho.initializeWithDefaults(this);
        OkHttpClient client = new OkHttpClient();
        client.networkInterceptors().add(new StethoInterceptor());
        Picasso picasso = new Picasso.Builder(this).downloader(new OkHttpDownloader(client)).build();
        Picasso.setSingletonInstance(picasso);
    }
}
```

![スクリーンショット_2015-12-26_1_31_15.png](https://qiita-image-store.s3.amazonaws.com/0/35733/0c1e5a22-20e1-42bd-04e4-7d4f2204468c.png "スクリーンショット_2015-12-26_1_31_15.png")

> ただ、読み込む画像が多いとアプリの動作がかなり重くなります。

また、まだ試したことはないのですが [Stetho-Realm](https://github.com/uPhyca/stetho-realm) を導入すると、Realm のデータの中身を Chrome Developer Tools で確認できるようになるようです。

## ③ EventBus

![スクリーンショット 2015-12-25 18.14.53.png](https://qiita-image-store.s3.amazonaws.com/0/35733/5d85f3af-d342-b724-6219-ccd41aa55323.png "スクリーンショット 2015-12-25 18.14.53.png")
> サイト：https://github.com/greenrobot/EventBus

いわゆる pub/sub で任意のインスタンスにイベントを通知することができます。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'de.greenrobot:eventbus:2.4.0'
}
```

イベントを送るには適当なイベント用のクラスを作り、`post` メソッドで投げるだけです。

![efb5b962-2b74-01c0-3b0f-18d120f662f9.png](https://qiita-image-store.s3.amazonaws.com/0/35733/99a1b563-6d8d-cbd4-7823-575053f50b77.png "efb5b962-2b74-01c0-3b0f-18d120f662f9.png")

> イベントを受け取る側は `EventBus.getDefault().register(<イベントを受けるインスタンス>)` としておいて EventBus 全体のイベントを購読しておく必要があります。

イベント用のクラスは普通の Java のクラスです。

![スクリーンショット 2015-12-26 20.39.36.png](https://qiita-image-store.s3.amazonaws.com/0/35733/8ecbedd1-b945-bd4d-3c59-57bf5efc9606.png "スクリーンショット 2015-12-26 20.39.36.png")

イベント用のクラスは通知を送る側のクラス、もしくは、通知を受ける側のクラスのインナークラスと定義しておくと、コード上わかりやすいです（１対多もしくは多対１のうち"１"の方）。<クラス名>.<イベント用クラス名> となるのでそのイベントがどのクラスから送られる/どのクラスへ送られるかが明確になるためです。

ただ EventBus を多用すると処理の繋がりが分かりにくくなるので、どうしてもコールバックの引き回しが難しい（コードが煩雑になる）ところに限定して利用するのがよいと思います。

ネイルブックでは、一覧画面から詳細画面を開き(別Activity)、詳細画面で行った操作を一覧画面にも反映する、という箇所で EventBus を利用しています。

![movie2.gif](https://qiita-image-store.s3.amazonaws.com/0/35733/03fbaee4-7d63-164f-7e66-c931a9b69fdc.gif "movie2.gif")

その他の使いどころとしてよくありそうなのは、ListView の Adapter や ViewHolder で起きたイベント(例えば ListView の各行にあるボタンのクリック等)を Adapter 利用元の Activity/Fragment へ通知するようなシチュエーションでしょうか。

> 最近は、RxJava で同様なことができるのかもしれません。

## ④ Butter Knife

![スクリーンショット 2015-12-21 19.15.11.png](https://qiita-image-store.s3.amazonaws.com/0/35733/e2520c4d-2098-acad-1745-19537482a46d.png "スクリーンショット 2015-12-21 19.15.11.png")
> サイト：http://jakewharton.github.io/butterknife/

View のインジェクト（レイアウトXMLファイル上の View の id と Activity/Fragment 上のインスタンス変数の対応づけ）で利用しています。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.jakewharton:butterknife:7.0.1'
}
```

`findViewById` の記述を無くせたり、クリックイベント等を簡潔に書けたりします。あわせて [android-apt](https://bitbucket.org/hvisser/android-apt) を導入しておくと、Butter Knife で生成されたコードが Android Studio から閲覧できます。

Android Studio 用のプラグインを導入しておくと更に捗ります。[こちら](http://qiita.com/hkusu/items/14a69dbdcb83ea0f1c24#-android-butterknife-zelezny)の投稿で紹介しました。

また、ネイルブックでは単なる View のインジェクトだけでなく、所謂 MVC でいう Controller への View のインジェクトで利用しています。この方法については、アドベントカレンダーの１５日めに詳しく書いたので、宜しければご覧ください。

- [太ったActivity/Fragmentをダイエット！Controllerへ処理を委譲する](http://qiita.com/hkusu/items/2e8fb40442190b440029)

## ⑤ LeakCanary

![スクリーンショット 2015-12-25 18.15.37.png](https://qiita-image-store.s3.amazonaws.com/0/35733/52f23e93-46a4-a96f-d29f-c79e6949b0c9.png "スクリーンショット 2015-12-25 18.15.37.png")
> サイト：https://github.com/square/leakcanary

リークの検出で利用しています。

```:build.gradle：プロジェクトへの導入
dependencies { 
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
}
```
> ネイルブックでは debug ビルド時でしか組み込まれないよう `debugCompile` で定義しています。

利用するには Application クラス等で次のように初期化するだけです。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        LeakCanary.install(this);
    }
}
```
> ネイルブックでは relese / debug ビルドで Application クラスのソースを分けています。

この状態でアプリを起動すると、端末に LeakCanary アプリが自動でインストールされ、

![スクリーンショット_2015-12-25_18_25_35.png](https://qiita-image-store.s3.amazonaws.com/0/35733/3bcfe347-7a63-0a0d-baec-8522de5637b2.png "スクリーンショット_2015-12-25_18_25_35.png")

リークを検出すると画面上にトーストで表示してくれます。LeakCanary アプリ上でリークの履歴を閲覧することも可能です。

## ⑥ Timber

![スクリーンショット 2015-12-21 19.10.31.png](https://qiita-image-store.s3.amazonaws.com/0/35733/dd1d5e20-047e-5a8c-0bb9-13ce0dd8ddcb.png "スクリーンショット 2015-12-21 19.10.31.png")
> サイト：https://github.com/JakeWharton/timber

デバッグ用のログ出力で利用しています。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.jakewharton.timber:timber:3.1.0'
}
```
> 最新バージョンは執筆時点で `4.1.0` ですが、`minSdkVersion` の関係でネイルブックでは `3.1.0` を使っています。

利用するには Application クラス等で次のように `Tree` というものを設定します。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        }
    }
}
```
> この `Tree` をカスタマイズすることにより、ログ出力を色々できるのですが、ここでは割愛します。ネイルブックでは標準で用意されている `DebugTree` を設定しています。

単純なログ出力は次のように書けます。

```java:
Timber.tag("hoge").i("piyo=%s", "fuga");
```
> %s %d 等で置き換えが出来る。

不要なログ出力が残ってしまう(コードの消し忘れ)問題に対しても有用です。こちらに書きました。

- [Timber で debug ビルド時のみにログを出力する](http://qiita.com/hkusu/items/d4f24141d11e05f57451)

## ⑦ Crashlytics (Fabric)

![スクリーンショット 2015-12-21 19.10.49.png](https://qiita-image-store.s3.amazonaws.com/0/35733/7279d3ac-a227-f28d-d129-04fc27e30903.png "スクリーンショット 2015-12-21 19.10.49.png")
> サイト：https://get.fabric.io/

クラッシュログの収集、および、開発版 Android アプリの社内配布で利用しています。

Crashlytics を利用するには、合わせて Android Studio 用のプラグインを導入します。[こちら](http://qiita.com/hkusu/items/14a69dbdcb83ea0f1c24#-fabric-for-android-studio)の投稿で紹介しました。

上記 プラグインを利用することにより自動で Gradle 用のファイルが修正されるので簡単にプロジェクトへ導入することが出来ます。

Crashlytics の初期化は次のように Application クラスで実施しておくのが良いかと思います。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Fabric.with(this, new Crashlytics());
    }
}
```

## ⑧ Google Analytics

![スクリーンショット 2015-12-21 19.11.23.png](https://qiita-image-store.s3.amazonaws.com/0/35733/7a2653a2-3d42-7400-8254-2c1368a29fb7.png "スクリーンショット 2015-12-21 19.11.23.png")
> サイト：https://www.google.co.jp/intl/ja_ALL/analytics/index.html


画面の表示回数やタップイベント回数、プッシュ通知の開封数等の計測で利用しています。グロースハックでは必須です。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.google.android.gms:play-services-analytics:8.3.0'
}
```

ちなみにプロジェクトへ Google の `play-services` 全てを読み込むのは無駄なので、ネイルブックでは上記のように `play-services` の中から必要なものだけを読み込んでいます。

使い方の説明については割愛しますが、ネイルブックでは Google Analytics と接続するコードをラップする static な Util 系メソッドを用意して、計測したい箇所からコールしています。また計測を色々なところに仕込んでいる場合はテストが大変（経験すると分かると思いますがユーザイベントを伴う非同期なクライアント・アプリケーションに計測を仕込むのは難しい）なので、デバッグ用のログ出力もされるようにしてあります。

## ⑨ Android Design Support Library

![スクリーンショット 2015-12-21 18.54.24.png](https://qiita-image-store.s3.amazonaws.com/0/35733/38639985-346a-be4d-837f-a9f840943fb0.png "スクリーンショット 2015-12-21 18.54.24.png")
> サイト：http://googledevjp.blogspot.jp/2015/07/android-design-support-library.html
> ※ Googleのブログです

Google 公式のライブラリです。マテリアルデザインの導入が簡単になります。ネイルブックでは ToolBar や左メニュー、タブなど、全般的に利用しています。

![movie3.gif](https://qiita-image-store.s3.amazonaws.com/0/35733/55181808-6039-9e78-55c5-0c963fbfb6e5.gif "movie3.gif")


```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.android.support:design:23.0.1'
}
```

> 執筆時点では `23.1.1` が最新ですが、`NavigationView` のヘッダが取得できないような挙動だったのでまだ最新バージョンは適用していません（もしかして回避する方法があるかも？）。

これも公式のライブラリなので色々なところに記事があると思うので使い方の説明については割愛します。

## ⑩ Google Material icons (Google)

![スクリーンショット 2015-12-21 18.24.59.png](https://qiita-image-store.s3.amazonaws.com/0/35733/a49a5366-7d08-696c-f136-15bf45ea6f82.png "スクリーンショット 2015-12-21 18.24.59.png")
> https://design.google.com/icons/

厳密にはライブラリではないのですが^^; Google が公式で用意しているマテリアルアイコンです。ネイルブックでも、これで済むアイコンはこれで済ませています。アプリを利用するユーザさんも、慣れてるアイコンの方が分かり易いというメリットがあるかと思います。

Android Studio から利用する場合は [Android Material Design Icon Generator Plugin](https://github.com/konifar/android-material-design-icon-generator-plugin) を利用すると捗ります。[こちら](http://qiita.com/hkusu/items/14a69dbdcb83ea0f1c24#-android-material-design-icon-generator)の投稿で紹介しました。

## [番外] Android Studio のプラグイン

ライブラリではありませんが、私が利用している Android Studio のプラグインはこちらにまとめています。

- [私が利用している Android Studio プラグイン 〜2015年版〜](http://qiita.com/hkusu/items/14a69dbdcb83ea0f1c24)


## ほか：MultiDex 対応

ライブラリをいろいろ導入していくと、メソッド数が 65K を超えコンパイルでエラーになってしまうことがあると思います。そうなった場合はプロジェクトを MultiDex に対応させる必要があります。

Android 5.0(Lollipop) 以上の端末向けであれば `build.gradle` で `multiDexEnabled true` とするだけなのですが、それ未満の端末向けに対応するには、次のようにサポートライブラリを導入します。

```:build.gradle：プロジェクトへの導入
dependencies { 
    compile 'com.android.support:multidex:1.0.1'
}
```

Application クラス等で、MultiDex を有効化します。

```java:SomeApplication.java
public class SomeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
           MultiDex.install(this);
        }
    }
}
```

# おわりに

上記以外に、ネットワーク通信まわりは Volley、JSON まわりは GSON、そのほか Facebook / Twitter 連係用のライブラリ、GCM(プッシュ通知)用の Google ライブラリなどなど。ネットワーク通信に関しては [Retrofit](http://square.github.io/retrofit/) に置き換えたいなあと思いつつ、なかなか進んでない感じです。

以上、全てではありませんが、[Android版ネイルブック](https://play.google.com/store/apps/details?id=jp.nailbook) で利用しているライブラリを紹介しました。

[株式会社スピカ](http://spika.co.jp)では一緒に切磋琢磨できるエンジニアの方を募集(Android以外も)していますので興味がある方は是非[こちら](https://www.wantedly.com/companies/spika/projects)をご覧ください！ Android に関しては Kotlin や RxJava、Realm を試してみようという機運とそれを実現するための裁量もあり、結構いろいろなことにチャレンジできる良い環境だと思います^^