SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Web APIで楽々Androidアプリ

Web APIの基本的な使い方

Web APIで楽々Androidアプリ(2)

HTTP通信処理

 次に、loadInBackgroundメソッドのなかで行う、HTTP通信処理を実装しましょう。

 HTTP通信を行う方法も非同期処理と同様に、いくつかの選択肢があります。ただWeb APIを呼び出す通信はシンプルなため、どの方法であっても大きな問題はありません。本稿では、Android SDKに含まれている、Apache HttpComponentsというライブラリのHttpClientオブジェクトを利用することにします。Apache HttpComponentsは、HTTP通信をサポートするオープンソースのクラスライブラリです。

 次に示すloadInBackgroundの処理は、HTTP通信が正常に完了すれば、その応答データを文字列として返し、もし通信に失敗すれば、nullを返すものです。

HttpAsyncLoader.javaの一部
@Override
public String loadInBackground() {

    HttpClient httpClient = new DefaultHttpClient();

    try {
        String responseBody = httpClient.execute(new HttpGet(this.url), // (1)

            // UTF-8でデコードするためhandleResponseをオーバーライドする (2)
            new ResponseHandler<String>() {

                @Override
                public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                    // レスポンスコードが、
                    // HttpStatus.SC_OK(HTTP 200)の場合のみ、結果を返す
                    if (HttpStatus.SC_OK ==
                        response.getStatusLine().getStatusCode()){
                            return EntityUtils.toString(
                                response.getEntity(), "UTF-8"); // (3)
                    }
                    return null;
                }
            });

        return responseBody;
    }
    catch (Exception e) {
        Log.e(this.getClass().getSimpleName(),e.getMessage());
    }
    finally {
        // 通信終了時は、接続を閉じる (4)
        httpClient.getConnectionManager().shutdown();
    }
    return null;
}

 ここでは、HttpClientインターフェースを実装した、基本となるDefaultHttpClientクラスを使っています。HttpClientを利用する上でのポイントは、以下の4つです。数字は、ソースコードのコメント内の数字に対応しています。

  1. HTTP GETメソッドを使う
  2. handleResponseを利用する
  3. UTF-8でデコードする
  4. 通信終了したら接続を閉じる

 Web APIでのデータを取得するには、一般的にHTTP GETメソッドを利用します。HTTP GETを実行するには、HttpGetクラスのインスタンスを、HttpClientインターフェースのexecuteメソッドの引数に指定します。

 DefaultHttpClientでHTTP通信の応答を受信するには、handleResponseというオブジェクトを利用するのが基本です。応答データがテキストであれば、一連の処理をかんたんに記述することができます。ただし、受信したテキストに日本語などを含む場合は、文字コードを指定して変換する必要があります。

 HTTP通信の応答時に、handleResponseメソッドがコールバックされますので、そこでEntityUtilsというオブジェクトを利用してテキストに変換します。

 通信の最後では、shutdownメソッドで接続を終了します。接続を終了するまでは、複数のリクエストを発行できますが、このHttpAsyncLoaderクラスでは、1度のリクエストで終了するようにしています。

AsyncTaskLoaderの初期化と呼び出し

 非同期で行うHTTP通信の実装ができましたので、今度はLoaderの初期化と、Loaderを実際に呼び出すコード、コールバックのメソッドを追加していきましょう。Loaderは、ActivityまたはFragmentから呼び出します。

ImaSoraActivity.javaの一部
@Override
protected void onCreate(Bundle savedInstanceState) {

    ~中略~

    // Bundleにはパラメータを保存する(1)
    Bundle bundle = new Bundle();

    // 大阪府の天気予報を返すAPIのURLを格納する(2)
    bundle.putString("url", "http://www.drk7.jp/weather/json/27.js");

    // LoaderManagerの初期化(3)
    getLoaderManager().initLoader(0, bundle, this); 
}

@Override
public Loader<String> onCreateLoader(int id, Bundle bundle) {

    // HttpAsyncLoaderの生成(4)
    HttpAsyncLoader loader = new HttpAsyncLoader(this, bundle.getString("url"));

    // Web APIの呼び出し(5)
    loader.forceLoad();
    return loader;
}

@Override
public void onLoadFinished(Loader<String> loader, String body) {

    // 実行結果の書き出し(6)
    if ( loader.getId() == 0 ) {
        if (body != null) {
            Log.d("ボディ",  body);
        }
    }
}

@Override
public void onLoaderReset(Loader<String> loader) {
    // 今回は何も処理しない
}

 まずはLoaderの初期化です。Loaderの初期化は、Activityが生成されるonCreateメソッドのタイミングで行います。

 コメント(1)のBundleクラスは、一時的にデータを保存するためのクラスです。連想配列のように、ある値と対応する文字列のペアで、データを格納することができます。

 ここでは、Bundleオブジェクトを、Loaderに引き渡すパラメータの受け渡しに利用しています。(2)では、作成したBundleオブジェクトに、urlという名前で、Web APIのURLを設定しています。

 (3)では、LoaderManagerクラスのinitLoaderメソッドを利用し、このActivityに対応づけるLoaderの初期化を行っています。なおLoaderManagerのインスタンスの取得は、直接生成するのではなく、getLoaderManagerメソッドを利用します。LoaderManagerのインスタンスは、Activityごとに1つ割り当てられ、何度getLoaderManagerを実行しても、同じLoaderManagerインスタンスが戻されます。

[構文]initLoaderメソッド
initLoader(int id, Bundle bundle, LoaderCallback)

id: Loaderを識別するID値(onCreateLoaderメソッドの第1引数に渡される)

bundle: パラメータ格納用(onCreateLoaderメソッドの第2引数に渡される)

LoaderCallback: LoaderCallbackインターフェースを実装したクラス

 initLoaderメソッドで、指定したIDのLoaderを初期化、生成します。引数には、複数のLoaderを区別するためのID、Loaderに渡すパラメータを保存したbundleオブジェクト、コールバックを受け取るActivityを指定します。

次のページ
天気予報のWeb API

この記事は参考になりましたか?

Web APIで楽々Androidアプリ連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7276 2013/08/01 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー