Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

2.09. ネットワーク通信

Hideyuki Kikuma edited this page May 14, 2013 · 24 revisions

この章では、ネットワーク通信について解説します。

目次

2つのクライアント

AndroidのHTTP通信を行うのclientははHttpURLConnectionとApache HttpClientがあります。

どちらのclientも出来る事に大きな差はありません。そのためアプリケーション内ではどちらかに統一するのが一般的です。 現在、新しくアプリケーションを作成するならばHttpURLConnectionの使用を推奨します。 Android2.2をサポート端末に含める場合はHttpClientの使用が推奨されていますが、アプリケーションの将来性を考えた場合、HttpURLConnectionを使用するのがよいでしょう。

サポートする範囲によって推奨するclientが変わってしまうのはわかりづらいですが、理由についてはこちらを参照してください。

パーミッション

ネットワークアクセスを行うためにはAndroidManifestファイルにネットワークアクセスを許可するパーミッションを追記する必要があります。 このパーミッションがない場合には、ネットワーク接続がエラーとなります。

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

また、ネットワークの接続状態を確認するためには

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

のパーミッションが必要になります。 このパーミッションを取得することで Wifiまたは3Gなどのネットワーク接続が可能な場合は通信を行い、接続が不可能な場合はオフラインモードでアプリケーションを動作させる。 と言ったようなことが可能になります。

ネットワーク接続を行うThread

ネットワーク接続の処理は予測不能な遅延を含む可能性があるため、ネットワーク接続の処理はUIThreadで処理を行なってはいけません。 そのため、ネットワーク接続は基本的に前章の非同期処理と組み合わせて使うことになります。

HttpURLConnection

参考:HttpURLConnection | Android Developers

HttpURLConnectionはweb上でデータの送受信をするためのclientです。 APIがシンプルで、サイズが小さいのでリソースに限りがあるAndroidに適しています。

Android2.2以前では、幾つかの問題のあるバグがあったため、推奨されていませんでした。特に、特定の条件でconnection poolを汚染することがありました。 この問題は下記のようなコードで回避ができます。

private void disableConnectionReuseIfNecessary() {
    // HTTP connection reuse which was buggy pre-froyo
    if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
        System.setProperty("http.keepAlive", "false");
    }
}

Android2.2以前の端末をサポートする場合はこのコードを入れておくほうがよいでしょう。

HttpURLConnectionの使用方法は

  1. URLオブジェクトのopenConnection()を呼び出すことによりインスタンスを取得出来ます。 ただし、openConnection()で取得できる型はURLConnection型なので、HttpURLConnectionへキャストする必要があります。
  2. 次に、必要なヘッダーを設定します。 Session cookieや認証情報、Content-typeなどを必要に応じて設定します。
  3. リクエストにbodyを設定する場合は、setDoOutput(true)でbodyが存在することを明示的に指定してください。 接続を確立後、getOutputStream()で取得したOutputStreamにbodyの内容を書き込みます。
  4. connect()で接続を確立します。 setDoOutput(false)の場合はこの段階でgetInputStream()でレスポンスを取得できるかと思います。 setDoOutput(treu)の場合は、getOutputStream()で取得したOutputStreamをcloseするまでデータの送信中のステータスになっているため、OutputStreamへの書き込みが完了したらcloseを呼び出すようにしてください。
  5. レスポンスをgetInputStream()で取得する。

上記のような手順でサーバーからのレスポンスを得ることができます。 ただし、実際にはgetInputStreamの前にgetResponseCode()でステータスコードなどを確認し、必要に応じてエラーハンドリングなどを行う必要があります。また、実際のアプリケーションでは、HttpURLConnectionをラッピングするクラスを作成し、個々のリクエストはラッパーを経由して行うと良いでしょう。

GET処理

        URL url = new URL("http://mixi.jp");
        HttpURLConnection connection = null;
        try {
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream is = connection.getInputStream();

            StringBuilder src = new StringBuilder();
            while (true) {
                byte[] line = new byte[1024];
                int size = is.read(line);
                if (size <= 0)
                    break;
                src.append(new String(line, "euc-jp"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            connection.disconnect();
        }

POST処理

        URL url = new URL("http://mixi.jp");
        HttpURLConnection connection = null;
        try {
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);

            String postData = "hoge=fuga&piyo=test";
            OutputStream os = connection.getOutputStream();
            os.write(postData.getBytes());
            os.flush();
            os.close();

            InputStream is = connection.getInputStream();

            StringBuilder src = new StringBuilder();
            while (true) {
                byte[] line = new byte[1024];
                int size = is.read(line);
                if (size <= 0)
                    break;
                src.append(new String(line, "euc-jp"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            connection.disconnect();
        }

HttpClient

HttpClientクライアントはApacheによって開発が進められているclientです。 HttpURLConnectionよりも扱いやすいですが、Androidでの利用はHttpURLConnectionが推奨されているので、簡単な紹介に留めます。 getの処理は下記のようになります。

        HttpClient client = new DefaultHttpClient();
        try {
            client.execute(new HttpGet("http://mixi.jp"),
                    new ResponseHandler<String>() {
                        public String handleResponse(HttpResponse response)
                                throws ClientProtocolException, IOException {
                            return EntityUtils.toString(response.getEntity());
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }

実習と課題

  1. (実習) HttpURLConnectionを利用してmixi.jpへアクセスをし、取得できたhtmlの文字列を画面に表示してください。
  2. (実習) HttpClientを利用して実習1と同様のことを行なってください。
  3. (課題) youtubeで日本で前日の評価の高い動画のタイトルをAPIで取得し表示してください。

GitHub Pagesへ移行しましたmixi-inc.github.ioへお願いします。

Clone this wiki locally