Androidアプリで通信処理を作る方法はいくつかあります。
今回はそのうちの一つであるHttpUrlConnectionを使った方法を簡単にではありますがまとめていきます。
特に、頻繁に使われるHTTPメソッドのGETとPOSTのサンプルコードを載せていきます。
環境
- Android Studio : 4.1.1
- Kotlin : 1.3.72-release-Studio4.1-5
GETリクエスト
GETリクエストのサンプルコードは以下です。
fun startGetRequest() {
// HttpURLConnectionの作成
val url = URL("ここにURL")
val connection = url.openConnection() as HttpURLConnection
try {
// ミリ秒単位でタイムアウトを設定
connection.connectTimeout = CONNECTION_TIMEOUT_MILLISECONDS
connection.readTimeout = READ_TIMEOUT_MILLISECONDS
// connection.requestMethod = "GET"
// connection.connect()
// Responseの読み出し
val statusCode = connection.responseCode
if (statusCode == HttpURLConnection.HTTP_OK) {
readStream(connection.inputStream)
}
} catch (exception: Exception) {
Log.e("Error", exception.toString())
} finally {
connection.disconnect()
}
}
POSTリクエスト
POSTリクエストのサンプルコードは以下です。
fun startPostRequest() {
// Bodyのデータ(サンプル)
val sendDataJson = "{\"id\":\"1234567890\",\"name\":\"hogehoge\"}"
val bodyData = sendDataJson.toByteArray()
// HttpURLConnectionの作成
val url = URL("ここにURL")
val connection = url.openConnection() as HttpURLConnection
try {
// ミリ秒単位でタイムアウトを設定
connection.connectTimeout = CONNECTION_TIMEOUT_MILLISECONDS
connection.readTimeout = READ_TIMEOUT_MILLISECONDS
// connection.requestMethod = "POST"
// Bodyへ書き込むを行う
connection.doOutput = true
// リクエストBodyのストリーミング有効化(どちらか片方を有効化)
// connection.setFixedLengthStreamingMode(bodyData.size)
connection.setChunkedStreamingMode(0)
// プロパティの設定
connection.setRequestProperty("Content-type", "application/json; charset=utf-8")
// connection.connect()
// Bodyの書き込み
val outputStream = connection.outputStream
outputStream.write(bodyData)
outputStream.flush()
outputStream.close()
// Responseの読み出し
val statusCode = connection.responseCode
if (statusCode == HttpURLConnection.HTTP_OK) {
readStream(connection.inputStream)
}
} catch (exception: Exception) {
Log.e("Error", exception.toString())
} finally {
connection.disconnect()
}
}
サンプルコードの補足
GETリクエストのサンプルコードの補足
GETリクエストのサンプルコードの補足をします。
以下の処理はコメントアウトしていますが、それぞれ有効にしても問題はありません。
// connection.requestMethod = "GET"
// connection.connect()
requestMethod
はHTTPリクエストメソッドの設定、connect()
は接続確立処理です。
requestMethod
requestMethod
はデフォルト値がGET
になっているため指定は不要です。
コードが理解しやすいようにGET
をあえて明記しておくのはありです。
connect()
connect()
は通信リンクの確立処理ですが記載は不要です。connect()
を記述すると明示的に接続確立処理を実行することになりますが、connect()
を記述しない場合はレスポンスデータを読み出しする際に処理が行われます。
つまり、今回のサンプルコードでは以下の処理のタイニングで接続処理が自動的に行われるため不要となります。
val statusCode = connection.responseCode
POSTリクエストのサンプルコードの補足
POSTリクエストのサンプルコードの補足をします。
requestMethod
requestMethod
処理はコメントアウトしていますが、それぞれ有効にしても問題ありません。
// connection.requestMethod = "POST"
// Bodyへ書き込むを行う
connection.doOutput = true
「GETリクエストのサンプルコードの補足」の中で「requestMethod
はデフォルト値がGET
になっているため指定は不要です。」と言いました。
しかし、POSTリクエストであるのにrequestMethod
にPOSTを設定していません。
これは、doOutput
にtrue
を設定すると内部的にPOSTのリクエストとして判別される動きとなるためです。
GET/POST以外のHTTTメソッドの場合には指定が必要になるので注意してください。
setFixedLengthStreamingModeとsetChunkedStreamingMode
無駄なメモリ使用と処理時間をかけないように、Bodyの長さが事前に判明している場合にはsetFixedLengthStreamingMode()
で長さを指定し、不明な場合はsetChunkedStreamingMode(0)
を呼ぶようにします。
// リクエストBodyのストリーミング有効化(どちらか片方有効)
// connection.setFixedLengthStreamingMode(bodyData.size)
connection.setChunkedStreamingMode(0)
Bodyの書き込み
今回、BodyでJSON
データを送信するため、Content-type
を設定してBodyにデータを書き込んでいます。
// プロパティの設定
connection.setRequestProperty("Content-type", "application/json; charset=utf-8")
// Bodyの書き込み
val outputStream = connection.outputStream
outputStream.write(bodyData)
outputStream.flush()
outputStream.close()
その他補足情報
今回、通信処理を行うため、まずAndroidManifest.xml
にインターネットへの接続許可を追加する必要があります。
<uses-permission android:name="android.permission.INTERNET" />
また、GET/POSTのサンプルコードではreadStream(connection.inputStream)
と記述していましたが、readStream()
メソッドは定義していませんでした。
どのようにレスポンスデータ読み出したいか、によって方法が異なるためです。
ですが、備忘録としてString
データとして読み出す一例としてを載せておきます。
fun readStream(inputStream: InputStream) {
val bufferedReader = BufferedReader(InputStreamReader(inputStream))
val responseBody = bufferedReader.use { it.readText() }
bufferedReader.close()
Log.d("レスポンスデータ : ", responseBody)
}
最後に、今回のサンプルコードはワーカースレッドで実行する必要があります。
通信処理をメインスレッドで実行するとandroid.os.NetworkOnMainThreadException
エラーが発生しますのでご注意ください。
関連記事
同じ通信処理をOkHttp3を使って実装する方法について記事を書いています。
HttpURLConnectionより簡単に実装ができますので、こちらについて読んでおくのも良いと思います。
参考ページ
今回のHttpURLConnectionの記事を書くにあたり、主に以下のdeveloperページを読み込みましたので、一読しておくと良いと思います。