techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Chuckを使ってRetrofitの通信を確認する

AndroidでHTTPの通信する際に利用されるOkHttp3用に作られたデバッグ用のツールChuckというのがあります。
Chuckの特徴はログとしてアウトプットするのではなく通信があった時に通知領域に表示され、通知を選択するとアプリが立ち上がり通信内容を閲覧することができます。
Logcatが使えない環境の場合には非常に有用です。

今回はRxJava+Retrofit+gson+chuckで通信内容を確認してみましょう。

まずは今回利用するライブラリをapp/build.gradleのdependenciesに下記を記載します。

    compile 'com.squareup.retrofit2:retrofit:2.2.0'
    compile 'com.squareup.okhttp3:okhttp:3.6.0'
    compile 'com.readystatesoftware.chuck:library:1.0.4'
    compile 'com.google.code.gson:gson:2.8.0'
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'
    compile 'io.reactivex:rxjava:1.2.7'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'

今回はGithubAPIのGETのリクエストを例に使います。
次のURLに対してリクエストするとします。
https://api.github.com

リクエストすると次のようなJSONが取得できます。 Github APIでどのようなAPIがあるか確認することができます。

{
  "current_user_url": "https://api.github.com/user",
  "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
  "authorizations_url": "https://api.github.com/authorizations",
  "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
  "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
  "emails_url": "https://api.github.com/user/emails",
  "emojis_url": "https://api.github.com/emojis",
  "events_url": "https://api.github.com/events",
  "feeds_url": "https://api.github.com/feeds",
  "followers_url": "https://api.github.com/user/followers",
  "following_url": "https://api.github.com/user/following{/target}",
  "gists_url": "https://api.github.com/gists{/gist_id}",
  "hub_url": "https://api.github.com/hub",
  "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
  "issues_url": "https://api.github.com/issues",
  "keys_url": "https://api.github.com/user/keys",
  "notifications_url": "https://api.github.com/notifications",
  "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
  "organization_url": "https://api.github.com/orgs/{org}",
  "public_gists_url": "https://api.github.com/gists/public",
  "rate_limit_url": "https://api.github.com/rate_limit",
  "repository_url": "https://api.github.com/repos/{owner}/{repo}",
  "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
  "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
  "starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
  "starred_gists_url": "https://api.github.com/gists/starred",
  "team_url": "https://api.github.com/teams",
  "user_url": "https://api.github.com/users/{user}",
  "user_organizations_url": "https://api.github.com/user/orgs",
  "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
  "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
}

これをGsonで読み込む必要があるため次のデータクラスを利用します。

public class GitHubApiData {

    @SerializedName("current_user_url")
    @Expose
    private String currentUserUrl;
    @SerializedName("current_user_authorizations_html_url")
    @Expose
    private String currentUserAuthorizationsHtmlUrl;
    @SerializedName("authorizations_url")
    @Expose
    private String authorizationsUrl;
    @SerializedName("code_search_url")
    @Expose
    private String codeSearchUrl;
    @SerializedName("commit_search_url")
    @Expose
    private String commitSearchUrl;
    @SerializedName("emails_url")
    @Expose
    private String emailsUrl;
    @SerializedName("emojis_url")
    @Expose
    private String emojisUrl;
    @SerializedName("events_url")
    @Expose
    private String eventsUrl;
    @SerializedName("feeds_url")
    @Expose
    private String feedsUrl;
    @SerializedName("followers_url")
    @Expose
    private String followersUrl;
    @SerializedName("following_url")
    @Expose
    private String followingUrl;
    @SerializedName("gists_url")
    @Expose
    private String gistsUrl;
    @SerializedName("hub_url")
    @Expose
    private String hubUrl;
    @SerializedName("issue_search_url")
    @Expose
    private String issueSearchUrl;
    @SerializedName("issues_url")
    @Expose
    private String issuesUrl;
    @SerializedName("keys_url")
    @Expose
    private String keysUrl;
    @SerializedName("notifications_url")
    @Expose
    private String notificationsUrl;
    @SerializedName("organization_repositories_url")
    @Expose
    private String organizationRepositoriesUrl;
    @SerializedName("organization_url")
    @Expose
    private String organizationUrl;
    @SerializedName("public_gists_url")
    @Expose
    private String publicGistsUrl;
    @SerializedName("rate_limit_url")
    @Expose
    private String rateLimitUrl;
    @SerializedName("repository_url")
    @Expose
    private String repositoryUrl;
    @SerializedName("repository_search_url")
    @Expose
    private String repositorySearchUrl;
    @SerializedName("current_user_repositories_url")
    @Expose
    private String currentUserRepositoriesUrl;
    @SerializedName("starred_url")
    @Expose
    private String starredUrl;
    @SerializedName("starred_gists_url")
    @Expose
    private String starredGistsUrl;
    @SerializedName("team_url")
    @Expose
    private String teamUrl;
    @SerializedName("user_url")
    @Expose
    private String userUrl;
    @SerializedName("user_organizations_url")
    @Expose
    private String userOrganizationsUrl;
    @SerializedName("user_repositories_url")
    @Expose
    private String userRepositoriesUrl;
    @SerializedName("user_search_url")
    @Expose
    private String userSearchUrl;

   <略>
}

最後にRetrofitのインターフェースを作成します。

public interface IGitHubApi {

    @GET("/")
    Observable<GitHubApiData> getGitHubApi();
}

今回の例はRootアクセスのなのでGETの指定は/だけの指定になります。

これで準備が整いました。
次のように実装します。

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        OkHttpClient okHttpClient = builder.addInterceptor(new ChuckInterceptor(this)).build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .build();
        IGitHubApi api = retrofit.create(IGitHubApi.class);
        api.getGithubApi()
                .subscribeOn(Schedulers.newThread())
                .subscribe();

1,2行目はOkHttpClient.Builderを作成し、Builderに対してaddInterceptorでChuckInterceptorを与えます。その際に引数にContextを渡します。
3行目にてRetrofitのRetrofit.Builderでclientを指定するようにしてOkHttpClientを渡しRetrofitのインスタンスを生成します。
9行目にて作成したインターフェースの生成を行い10行目にて実行しています。

これを実行した結果、通知は次のように表示されます。

f:id:muchiki0226:20170305202847p:plain:w400

その通知を選択すると次のように表示されます。

f:id:muchiki0226:20170305202851p:plain:w400

リクエストがあるたびに履歴が追加され上図のリストが追加されていきます。
一つを選択すると下図のように表示されます。

f:id:muchiki0226:20170305202855p:plain:w400

どういったリクエストをしたのかをOVERVIEWで閲覧することができます。
さらにRESPONSEを選ぶとGETリクエストの返却されてきたデータが閲覧することができます。

f:id:muchiki0226:20170305202858p:plain:w400

これによってLogcatを使わないでも通信した内容を確認することができます。