FlipperでAndroidアプリのデバッグをする


はじめに

恥ずかしながら今更Flipperの存在を知ったもののQiitaに記事がなかったので軽くまとめておきます。
今回試せたのはAndroidの方だけでiOSの方は試せていないのでどなたかやってみてください

Flipperとは?

Facebook社が開発しているAndroid, iOS両方に対応しているデバッグツールです。
以前はSonarという名前だったようです。

公式サイト

でもStethoありましたよね?

と思っていたらそのことに関するStetho Guidanceというページが有りました。
原文を読んだ感じ、StethoはAndroidツールだったしChrome開発ツールはWeb向けだったので、アプリ開発に特化した体験を提供するにあたり専用のツールを作ったようです。
また、別にStethoが使えなくなるというわけでもなさそうですのでひと安心です。

何が違うの?

  • StethoはAndroidのみしか対応していなかった、FlipperはiOSにも対応している
  • プラグインで機能が拡張可能
  • 今のところSQLiteの中身を見れるのはStethoだけっぽい(2019/02/08現在)
  • chrome://inspect でウインドウを都度開かなくて良いのが地味に助かる

出来ること

Logs

ログ種別が色分けされて見やすいですが、正直AndroidStudioの方で充分そう。

LayoutInspector

ViewHierarchyが見られます

Network

OkHttpClientのInterceptorにFlipperOkhttpInterceptorを渡すことで、アプリからの通信内容が見られます。
この辺りもStethoで出来ていたことですね。

Sandbox

予め設定をしておく事によってFlipper経由で入力した値を取得できるようになる模様、iOSは未対応。
RemoteConfig的な解釈でいますが、もっとよく理解したら追記します。

SharedPreferences

SharedPreferencesの状態を取得、変更履歴の表示(イベントが発生するとChangelogが更新される)出来る上に、値の書き換えまで出来ます。
iOSの方はUserDefaultっぽいですね。
StethoよりUIは使いやすくなっているものの、SharedPreferencesのファイル名をプラグインの追加時に渡さねばならず、なんでも覗けたStethoのほうが便利だった気が

LeakCanary

LeakCanaryで検出されたリークが自動的に表示されるようです。

CrashReportPlugin

アプリがクラッシュするとFlipperに通知が表示され"Open in Logs"ボタンを押すとLogsの方で該当箇所が開かれるようです。
α版のようなので動作は怪しそう…

導入方法

Getting Startedに沿っています。

Mac側

ダウンロードします。

Android側

今回はdebugビルドのみ有効にしたいものとします。

大まかな流れとしては
1. app/src/debugフォルダを作成する
2. その配下にDebugAppというクラスを作成する
3. AndroidManifestも作成し、デバッグビルド時のApplicationクラスを上書きする

手順はデバッグ時のみStetho, LeakCanary, StrictModeを入れるを参考にしています。

app/build.gradle
repositories {
  jcenter()
}

dependencies {
    debugImplementation 'com.facebook.flipper:flipper:0.15.0'
    debugImplementation 'com.facebook.soloader:soloader:0.6.0'
}

ちなみにいつも忘れて5分くらいハマるのですが、debugディレクトリ側で定義するクラスから継承するために大元のAppクラスはopen classにしておく必要があります。
また、ここでは試しにLayoutInspectorとSharedPreferencesのプラグインを有効にしています。

path/to/debug/src/DebugApp.kt
class DebugApp : App() {

    override fun onCreate() {
        super.onCreate()
        initFlipper()
    }

    private fun initFlipper() {
        SoLoader.init(
            this,
            false
        )
        if (FlipperUtils.shouldEnableFlipper(this)) {
            AndroidFlipperClient.getInstance(this).apply {
                addPlugin(
                    InspectorFlipperPlugin(
                        this@DebugApp,
                        DescriptorMapping.withDefaults()
                    )
                )
                addPlugin(
                    SharedPreferencesFlipperPlugin(
                        this@DebugApp,
                        PrefsConst.FILE_NAME
                    )
                )
            }.start()
        }
    }
}

デバッグビルド用のAndroidManifest.xmlにINTERNETとACCESS_WIFI_STATEのパーミッションを追加します。
更に公式のドキュメントで推奨されていたのでFlipperDiagnosticActivityも定義しています。

app/src/debug/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

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

    <application
        android:name=".DebugApp"
        tools:replace="android:name">
        <activity android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
            android:exported="true"/>
    </application>

</manifest>

ここまで設定したらあとはdebugビルドするだけで動くはずです。

おわりに

全体的にStethoよりもUIは見やすいものの、DBの中身を覗けないのでSQLiteを使っているなら今の所Stethoは外せないかなという印象でした。
とはいえ、Issueは上がっているのと、プラグイン開発も出来るようなのでそのへんの課題が解決されるのは時間の問題かもしれません。

現時点ではデバッグビルド時のみ有効にする設定にしておけば本番コードへの影響も無い1ので、Stethoと併用して様子見がベターかなという結論です。

興味を持った方は、最新の情報を得るためにも公式サイトを見るのをおすすめします。
この記事の内容はきっとすぐに陳腐化します、するはず、してくれ。


  1. ただしOkHttpを使うとなると話が別です、現状no-opのパッケージも無いので一工夫が必要。