Facebookのライブラリ、Stetho便利ですよね。
セキュリティ的にバックドアになるものなのでreleaseビルドでは関連コードは確実に除きたいものです。
ただ、releaseビルドに含まないためのからのlibraryがないのでちょっと面倒です。
すでにqiitaにも幾つか方法が投稿されていたのでまとめてみました。
まず、共通する部分として、debugビルドにしかstetho関連ライブラリを含まない、としたいのでbuild.gradleを次のようにします。
dependencies {
....
debugCompile 'com.facebook.stetho:stetho:1.3.1'
debugCompile 'com.facebook.stetho:stetho-okhttp3:1.3.1'
}
buildTypeによって参照するクラスを書き換える方法
Create stetho-stub for convenient removal from release builds #16
公式githubのissueの中で議論されていた方法です。
この方法を見てこの記事を書こうと思いました。
build.gradleの中でBuildConfigに追加するクラスをbuildTypeに応じて変える、という方法です。
賢いなぁ、と思いました。
debug {
...
// ここでBuildConfig.STETHOとして追加するクラスを変える。
buildConfigField 'mypackage.util.StethoHelper', 'STETHO', 'new flipboard.util.RealStethoHelper()'
}
release {
...
// releaseビルドではfakeクラスを追加する
buildConfigField 'mypackage.util.StethoHelper', 'STETHO', 'new flipboard.util.FakeStethoHelper()'
}
そしてまず、mainの中にどちらでも使うInterfaceと空クラスを定義します。
// StethoHelper interface, AKA "NetworkEventReporterImpl"
public interface StethoHelper {
void init(Context context);
void configureInterceptor(OkHttpClient httpClient);
}
public class FakeStethoHelper implements StethoHelper {
@Override
public void init(Context context) {
// Noop
}
@Override
public void configureInterceptor(OkHttpClient httpClient) {
// Noop
}
}
次にdebugの中に本当にstethoを使うクラスを作成します。
この中でだけstethoを参照することでdebugCompileでもビルドできるようにしていますね。
public class RealStethoHelper implements StethoHelper {
@Override
public void init(Context context) {
Stetho.initializeWithDefaults(context);
}
@Override
public void configureInterceptor(OkHttpClient httpClient) {
httpClient.networkInterceptors().add(new StethoInterceptor());
}
}
実際にstethoを使うクラスは分ける必要がありません。
該当箇所でStethoHelperクラスにinitやinterceptの設定をすればいいだけです。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// In your application class's onCreate()
BuildConfig.STETHO.init(this);
}
}
// In your network stack
BuildConfig.STETHO.configureInterceptor(this.httpClient);
この方法は初回こそ若干build.gradleに書いたり、helperクラスに書いたりする必要がありますが、使う箇所が増えてもhelperを拡張していけばいいだけですし、メンテナンスの時に便利そうです。
-
- 参照場所やbuildTypeが増えてもメンテナンスしやすそう
-
- ちょっと賢そう。
-
- はじめに追加する部分が多い。
debugビルドでのみinitする方法
デバッグ時のみStetho, LeakCanary, StrictModeを入れる
Applicationクラスを共通用のものを継承したDebugApplicationクラスを作って、debugビルドではそちらに上書きする、という方法ですね。
これが一番簡単な方法かと思います。
他のライブラリについても書かれているので、Stetho部分だけ抜き出すと、
public class DebugApplication extends MyApplication {
@Override
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(context);
}
}
<application
android:name=".DebugApplication"
tools:replace="android:name" />
ですね。
でもこれだと一つ問題があってbuild.gradleでstetho-okhttpを参照していますが、okhttpにinterceptorを入れる箇所でもstethoを参照してしまっているため、このままだとbuildできませんでした。
helperを別に作るなど、他の方法を組み合わせるのがいいと思います。
-
- コード量が少なくて楽
-
- stethoの初期化時にしか使えない。(他の部分は増やしていく必要がある)
元ネタ
Stetho for Android debug builds only
releaseビルドでは同名クラスを作成する方法。
もう一つはreleaseビルドように同名のダミークラスを用意する方法です。
例がkotlinで書かれているので、同じようにjavaでもあげてみます。
public class Stetho {
public static void initializeWithDefaults(Context context) {
// 空実装
}
}
public class StethoInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
return null; // 空実装
}
}
これなら、okhttpのinterceptor等もreleaseビルドで参照できて、いいと思います。
ただ、使っている関連クラスが増えたり、methodの形式が変わったりすると同じ構成を実現できるように維持する必要があるため、メンテナンスが煩雑になりそうです。
-
- 追記するコード量は少なめ
-
- どちらのコードも特殊なことをしなくて良い
-
- 参照クラスを増やすたびにダミークラスやメソッドを追記する必要がある
ちなみに
本文と関係ありませんが、stethoをupdate?追加した際、releaseビルドができない問題に遭遇しました。
上の記事の内容の通りで、明示的にjsr305をdependenciesに含めたら解決しました。
dependencies {
compile 'com.google.code.findbugs:jsr305:2.0.1'
}
ご参考までに。