【Android】Flipperを使ったデバッグ方法

## [Flipper](https://fbflipper.com/)

> Facebookが開発しているAndroid/iOSアプリのデータの参照等が行える便利ツール

これまでもAndroidであれば [Stetho](http://facebook.github.io/stetho/) や [Hyperion-Android](https://github.com/willowtreeapps/Hyperion-Android)などのデバッグツールがありましたが、開発中にサクッと色々なログを見れたりする点ではFlipperだと良さそうな気がします :sparkles: またプラグインを追加でき拡張できたりして使い勝手が良さそうな印象です。

### クライアントツール :eyes: 
[Mac](https://www.facebook.com/fbflipper/public/mac), [Linux](https://www.facebook.com/fbflipper/public/linux), [Windows](https://www.facebook.com/fbflipper/public/windows)用の専用クライアントを使用してログを確認します。

起動するとこんな感じのアプリです。
<img width="500" alt="スクリーンショット 2019-10-06 16.26.13.png (760.2 kB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/73202434-21f9-f290-8af4-8622fecf8033.png">

###  :computer:環境構築
****
扱いたいアプリの `AndroidManifest.xml`に以下を追加

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
```

※ Build Variants が debug の時のみ有効にしたい場合などは `debug/AndroidManifest.xml` に追加する等する

`app/build.gradle` に依存ライブラリを追加

```gradle:app/build.gradle
repositories {
  jcenter()
}

dependencies {
  // Build Variants が debug の時のみ有効
  debugImplementation 'com.facebook.flipper:flipper:0.25.0'
  debugImplementation 'com.facebook.soloader:soloader:0.8.0'
  // Build Variants が release の時のみ有効
  releaseImplementation 'com.facebook.flipper:flipper-noop:0.25.0'
}
```

Applicationを継承したカスタムのApplicationのonCreate内で以下を追加する

```kotlin
        SoLoader.init(this,false)
        if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
            val client = AndroidFlipperClient.getInstance(this).apply {
                // pluginを追加する場合ここに追加していく
                addPlugin(DatabasesFlipperPlugin(this@RootApplication))
            }
            client.start()
        }
```

あとはアプリを実行して、ダウンロードしたクライアントツールを使って確認すると
以下の様にログやデータが確認出来ます。
<img width="1512" alt="スクリーンショット 2019-10-06 16.39.07.png (1.2 MB)" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/bf3b460e-0304-6aba-1887-84812444df19.png">

クライアントツールの他機能として、プラグイン追加しない状態だと
- CPUの情報
- Crash Reporter のログ
- Logs
- スクリーンキャプチャ
- 動画

が使える様でした :sparkles: 

### :electric_plug:  プラグイン
****

#### Layout Inspector
Viewの階層の詳細が見れます。

```kotlin
if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
    val client = AndroidFlipperClient.getInstance(this).apply {
        ....
        // Layout Inspector
        val descriptorMapping = DescriptorMapping.withDefaults()
        addPlugin(InspectorFlipperPlugin(this@RootApplication, descriptorMapping))
    }
    client.start()
}
```
addPluginに上記を追加してアプリを起動すると `Layout` 項目が増えていて
Viewの状態を確認できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/c208f90b-7707-8525-58de-66c15cb4bee3.png" width="600" />

####  Network
OkHttpClientのInterceptorにFlipperOkhttpInterceptorを設定することで通信ログを見れる様になります。
こちらは事前に以下のdependenciesを追加する必要があります。

```gradle
debugImplementation 'com.facebook.flipper:flipper-network-plugin:0.25.0'
```

```kotlin
if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
    val client = AndroidFlipperClient.getInstance(this).apply {
        ....
        // Network
        val networkPlugin = NetworkFlipperPlugin()
        addPlugin(networkPlugin)
    }
    client.start()
}
```

#### Shared Preferences

Shared Preferencesの確認や、変更等が行えます。
また、変更された内容はCHANGELOGとして確認できます。

```kotlin
if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
    val client = AndroidFlipperClient.getInstance(this).apply {
        ....
        // Shared Preferences
        addPlugin(SharedPreferencesFlipperPlugin(this@RootApplication, "shared_pref"))
    }
    client.start()
}
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/deffaac4-f94a-8989-5e00-6ab5d4a603b4.png" width="600" />

#### LeakCanary
メモリリーク検出の [LeakCanary](https://square.github.io/leakcanary/)用のプラグインもあります。
こちらも事前に以下をdependencisに追加。

```gradle
    debugImplementation 'com.facebook.flipper:flipper-leakcanary-plugin:0.25.0'
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
```

```kotlin
if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
    val client = AndroidFlipperClient.getInstance(this).apply {
        ....
        // LeakCanary
        addPlugin(LeakCanaryFlipperPlugin())
    }
    client.start()
}
```
実際に使う場合、`RecordLeakService` をlistenerServiceに登録する

```kotlin
        val refWatcher = LeakCanary.refWatcher(this)
            .listenerServiceClass(RecordLeakService::class.java)
            .buildAndInstall()
        refWatcher.watch(this)
```

```xml:AndroidManifest.xml
<service android:name="com.facebook.flipper.plugins.leakcanary.RecordLeakService" />
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/94a4ebef-5295-b5c6-cc82-3bc5ff198dc0.png" width="600" />

#### Database
テーブルの中身を確認できたり、SQLが使えたり、テーブルの詳細の確認などができます。
※今回はroomを使用して実装しました。

```kotlin
if(BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)){
    val client = AndroidFlipperClient.getInstance(this).apply {
        addPlugin(DatabasesFlipperPlugin(this@RootApplication))
    }
    client.start()
}
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299271/214e3dda-4a95-503a-56aa-474018ec9797.png" width="600" />

### :link: 参考にさせて頂いたURL
****
- [【Android】デバッグツールライブラリFlipperを使ってみました | ITcowork Staff Blog](https://www.itcowork.co.jp/blog/?p=5310)