LoginSignup
133
145

More than 3 years have passed since last update.

AndroidでHTTP通信したいときの手段まとめ

Last updated at Posted at 2017-03-26

2019/04/25更新
AndroidでHTTP通信するときの手段についてまとめておきます。

サーバー側の流行やプログラミングのパラダイム変化によって今後もどんどん新しい、便利なライブラリが出てくるでしょう。

HttpUrlConnection(ライブラリ使わずJava標準のURLConnectionを使う方法)

  • Apache系(Apache HttpClient,DefaultHttpClient,AndroidHttpClient)引退にともない、低レベルAPIとしてはこちらが推奨に。 (以前はバグがあった)

Example

HttpUrlConnectionでGETのサンプルコード

GET
    public static String get(String endpoint, String encoding, Map<String, String> headers) throws IOException {

        final int TIMEOUT_MILLIS = 0;// タイムアウトミリ秒:0は無限

        final StringBuffer sb = new StringBuffer("");

        HttpURLConnection httpConn = null;
        BufferedReader br = null;
        InputStream is = null;
        InputStreamReader isr = null;

        try {
            URL url = new URL(endpoint);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setConnectTimeout(TIMEOUT_MILLIS);// 接続にかかる時間
            httpConn.setReadTimeout(TIMEOUT_MILLIS);// データの読み込みにかかる時間
            httpConn.setRequestMethod("GET");// HTTPメソッド
            httpConn.setUseCaches(false);// キャッシュ利用
            httpConn.setDoOutput(false);// リクエストのボディの送信を許可(GETのときはfalse,POSTのときはtrueにする)
            httpConn.setDoInput(true);// レスポンスのボディの受信を許可

            // HTTPヘッダをセット
            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpConn.setRequestProperty(key, headers.get(key));// HTTPヘッダをセット
                }
            }
            httpConn.connect();

            final int responseCode = httpConn.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {

                is = httpConn.getInputStream();
                isr = new InputStreamReader(is, encoding);
                br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
            } else {
                // If responseCode is not HTTP_OK
            }

        } catch (IOException e) {
            throw e;
        } finally {
            // fortify safeかつJava1.6 compliantなclose処理
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            if (httpConn != null) {
                httpConn.disconnect();
            }
        }
        return sb.toString();
    }
GET呼び出し方
        //HTTPヘッダ(指定したければ)
        Map<String,String> headers=new HashMap<String,String>();
        headers.put("X-Example-Header","Example-Value");
        String resultStr = get("http://hogehoge/foofoo", "UTF-8", headers);

HttpUrlConnectionでPOST(JSON文字列をPOSTする例)

POST
   public static String post(String endpoint, String encoding, Map<String, String> headers, String jsonString) throws IOException {

        final int TIMEOUT_MILLIS = 0;// タイムアウトミリ秒:0は無限

        final StringBuffer sb = new StringBuffer("");

        HttpURLConnection httpConn = null;
        BufferedReader br = null;
        InputStream is = null;
        InputStreamReader isr = null;

        try {
            URL url = new URL(endpoint);
            httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setConnectTimeout(TIMEOUT_MILLIS);// 接続にかかる時間
            httpConn.setReadTimeout(TIMEOUT_MILLIS);// データの読み込みにかかる時間
            httpConn.setRequestMethod("POST");// HTTPメソッド
            httpConn.setUseCaches(false);// キャッシュ利用
            httpConn.setDoOutput(true);// リクエストのボディの送信を許可(GETのときはfalse,POSTのときはtrueにする)
            httpConn.setDoInput(true);// レスポンスのボディの受信を許可

            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpConn.setRequestProperty(key, headers.get(key));// HTTPヘッダをセット
                }
            }

            OutputStream os = httpConn.getOutputStream();
            final boolean autoFlash = true;
            PrintStream ps = new PrintStream(os, autoFlash, encoding);
            ps.print(jsonString);
            ps.close();

            final int responseCode = httpConn.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {

                is = httpConn.getInputStream();
                isr = new InputStreamReader(is, encoding);
                br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
            } else {
                // If responseCode is not HTTP_OK
            }

        } catch (IOException e) {
            throw e;
        } finally {
            // fortify safeかつJava1.6 compliantなclose処理
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            if (httpConn != null) {
                httpConn.disconnect();
            }
        }
        return sb.toString();
    }
POST呼び出し方
        String postJson = "[{\"message\":{\"number\":\"1\",\"value\":\"Hello\"}}]";
        Map<String, String> headers = new HashMap<String, String>(); // HTTPヘッダ(指定したければ)
        headers.put("X-Example-Header", "Example-Value");
        String postResult = post("http://hogehoge/foofoo", "UTF-8", headers, postJson);

 脱線しますが、Android盤のjava.net.HttpURLConnectionは、本家JDKと同じインタフェースはもっていますが、AndroidのJava実装は本家OracleJDKとは違います(※1)ので、Oracle謹製のJavaランタイムで動作していても、Androidで動作しないことは多々ありました。(※2)

(※1)AndroidのJDKはApache HarmonyベースからOpenJDKベースへと変化しています。
(※2)Pure Java(のみ)でテストされたライブラリをそのままもってくると痛い目をみます。

Apache系(Apache HttpClient,DefaultHttpClient,AndroidHttpClient)

  • 5.1でDeprecatedになり、6.0で削除されました
  • 経過措置はあるものの、もう使用しないほうがいいでしょう

volley

  • Androidでよくあるシーン(非同期とか)に対応したいろいろ便利なvolley
final TextView mTextView = (TextView) findViewById(R.id.text);
...

// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Display the first 500 characters of the response string.
        mTextView.setText("Response is: "+ response.substring(0,500));
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mTextView.setText("That didn't work!");
    }
});
// Add the request to the RequestQueue.
queue.add(stringRequest);

https://developer.android.com/training/volley/simple.html より抜粋

OkHttp3

http://square.github.io/okhttp/
- 最近人気がある(らしい)
- 現時点で最新は OkHttp 3系

maven/gradle

dependencies {
    compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.1'
}

Example

OkHttp3でのREST操作(Request)のつくりかた

GET

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

   public void doGet(String url) throws IOException {

        final Request request = new Request.Builder().url(url).build();
        final OkHttpClient client = new OkHttpClient.Builder().build();

        //同期呼び出し
        Response response = client.newCall(request).execute();
        //結果を表示
        System.out.println(response.body().string());
    }

POST

  • Form POSTしたい場合
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

   public void doFormPost(String url) throws IOException {
        final FormBody.Builder formBodyBuilder = new FormBody.Builder();
        formBodyBuilder.add("param_name", "param_value");

        final Request request = new Request.Builder()
                .url(url)
                .header("User-Agent", "Example client")
                .post(formBodyBuilder.build())
                .build();
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //同期呼び出し
        Response response = client.newCall(request).execute();
        //結果を表示
        System.out.println(response.body().string());
    }
  • JSON をまるっとPOSTしたい場合
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

    public void doPost(String url, String jsonString) throws IOException {
        okhttp3.MediaType mediaTypeJson = okhttp3.MediaType.parse("application/json; charset=utf-8");

        RequestBody requestBody = RequestBody.create(mediaTypeJson, jsonString);

        final Request request = new Request.Builder()
                .url(url)
                .post(requestBody)//POST指定
                .build();
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //同期呼び出し
        Response response = client.newCall(request).execute();
        //結果を表示
        System.out.println(response.body().string());
    }

PUT

final Builder formBodyBuilder = new FormBody.Builder();
    formBodyBuilder.add("param_name","param_value");

    final Request request = new Request.Builder()
            .url(url)
            .put(formBodyBuilder.build())
            .build();
    OkHttpClient client = new OkHttpClient.Builder()
                .build();
    Response response = client.newCall(request).execute();//同期呼び出し

DELETE

    final Request request = new Request.Builder()
            .url(url)
            .delete()
            .build();
    OkHttpClient client = new OkHttpClient.Builder()
                .build();
    Response response = client.newCall(request).execute();//同期呼び出し

同期呼び出し

OkHttpClient client = new OkHttpClient.Builder()
                .build();
Response response = client.newCall(request).execute();

非同期呼び出し

OkHttpClient client = new OkHttpClient.Builder()
                .build();

client.newCall(request).enqueue(new okhttp3.Callback() {

@Override
public void onResponse(Call call, Response response) throws IOException {

final String resString = response.body().string();
 //view更新のときは handler#post()する
}

@Override
public void onFailure(Call call, IOException arg1) {

}
});

Retrofit2

http://square.github.io/retrofit/
- OkHttp開発元による「RESTならまかせてよ!」というライブラリ。
- REST操作(GET,POST,PUT,DELETE)を少ない記述で実現できる
- 現時点で最新は Retrofit 2.x系

maven/gralde

Example

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

( http://square.github.io/retrofit/ より抜粋)

HTTP通信と一緒に使う道具たち

JSONパーサー

JSONをモデルクラス(POJO)にマッピングしたい

JSONパーサーを使うときに、GSONやJacksonに対応したモデルクラスを自動生成してくれるサイト

生のJSONやJSON Schemaから、GSONやJacksonに対応したモデルクラスを自動生成してくれる

GSON

maven/gradle
https://mvnrepository.com/artifact/com.google.code.gson/gson

設定例

build.gradle
 compile 'com.google.code.gson:gson:2.8.5'

Jackson

(おまけ)JacksonをJSON ParserとしてAndroidで使う時の注意

compile 'com.fasterxml.jackson.core:jackson-databind:2.8.6'

gradleのビルド時にJACKSONのLICENSEファイルが重複して以下のようなエラーメッセージがでるので、

Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE

アプリレベルのbuild.gradleに以下のように書いておくとよいでしょう。

build.gradle
android {
 中略
 packagingOptions {

        exclude 'META-INF/LICENSE'

    }
}

JSONの操作については、↓に詳しくまとめました
JSONをJavaに、JavaをJSONにする ~GSONとJacksonの使用方法~

リアクティブプログラミング

RxJava/RxAndroid
https://mvnrepository.com/artifact/io.reactivex/rxandroid
https://mvnrepository.com/artifact/io.reactivex/rxjava

133
145
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
133
145