StethoはFacebookが公開している超便利ライブラリです。
通信内容を母艦のChrome Developer Toolsで丸裸にできます。
詳しくは StethoでAndroidのNetwork Performanceを見る - Qiita 参照。
Twitter4JでStethoを使う場合はちょっとクセがあるのでその解説を備忘録代わりに書いておきます。
デバッグビルドでのみ動作するようにします。
また、Twitter4J(twitter4j-http2-support)の動作の都合上、最初の通信後ではないとOkHttpインスタンスが取得できないので、この方法だと最初の通信だけはinspectできません。
環境
version | 備考 | |
---|---|---|
Twitter4J | 4.0.3 | *1 |
OkHttp | 2.3.0 | *1 |
AndroidStudio | 1.2 Beta3 |
*1 カスタマイズ版を使っています。
Set-up
Download
build.gradle
dependencies {
debugCompile 'com.facebook.stetho:stetho:1.1.0'
debugCompile 'com.facebook.stetho:stetho-okhttp:1.1.0'
}
通常は上記で十分なんですが個人的に okhttp をカスタマイズしているので、自力で stetho-okhttp をビルドし直して下記のように書いています。
build.gradle
dependencies {
compile files('libs/okhttp-2.3.0.jar')
compile 'com.squareup.okio:okio:1.3.0'
debugCompile 'com.facebook.stetho:stetho:1.1.0'
debugCompile files('libs/stetho-okhttp-1.1.0-SNAPSHOT.jar')
}
Setup
いわゆるApplicationクラスでStethoの初期化を行います。
main/java/com/twitpane/App.java
public class App extends AppBase {
...
}
debug/java/com/twitpane/AppBase.java
package com.twitpane;
import android.app.Application;
import com.facebook.stetho.Stetho;
import com.facebook.stetho.okhttp.StethoInterceptor;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.twitpane.util.TPUtil;
import java.util.List;
import jp.takke.util.MyLog;
import twitter4j.Twitter;
public class AppBase extends Application {
@Override
public void onCreate() {
super.onCreate();
// デバッグビルドでのみStethoを有効化
Stetho.initialize(
Stetho.newInitializerBuilder(this)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
.build());
}
public static void onTwitterConnectionEstablished(Twitter twitter) {
try {
final twitter4j.AlternativeHttpClientImpl http = TPUtil.getHttpClientImpl(twitter);
final OkHttpClient client = TPUtil.getOkHttpClient(http);
if (client != null) {
final List<Interceptor> interceptors = client.networkInterceptors();
if (interceptors.size() == 0) {
interceptors.add(new StethoInterceptor());
}
}
} catch (Exception e) {
MyLog.e(e);
}
}
}
release/java/com/twitpane/AppBase.java
package com.twitpane;
import android.app.Application;
import twitter4j.Twitter;
public class AppBase extends Application {
@Override
public void onCreate() {
super.onCreate();
}
public static void onTwitterConnectionEstablished(Twitter twitter) {
}
}
TPUtil.java
...
public static twitter4j.AlternativeHttpClientImpl getHttpClientImpl(
final Twitter twitter) throws ClassNotFoundException,
NoSuchFieldException, IllegalAccessException {
final Class<?> clazz = Class.forName("twitter4j.TwitterBaseImpl");
final Field f1 = clazz.getDeclaredField("http");
f1.setAccessible(true);
final HttpClient impl = (HttpClient) f1.get(twitter);
return (twitter4j.AlternativeHttpClientImpl) impl;
}
public static OkHttpClient getOkHttpClient(AlternativeHttpClientImpl http) {
try {
final Field f3 = ((Object) http).getClass().getDeclaredField("okHttpClient");
f3.setAccessible(true);
// client = http.okHttpClient
return (OkHttpClient) f3.get(http);
} catch (Exception e) {
MyLog.e(e);
return null;
}
}
MyLog.java は省略
で、通信後におもむろに AppBase.onTwitterConnectionEstablished を呼び出してあげればOK。
TimelineFragment.java
...
result = twitter.getHomeTimeline(mPaging);
AppBase.onTwitterConnectionEstablished(twitter);
...