diadia

興味があることをやってみる。自分のメモを残しておきます。

Kotlin OkHttpを使ってHttp通信

HttpUrlConnectionについて

Androidアプリケーションを開発するにいたり、最初に本で学習した。その時にAsncTaskとHttpUrlConnectionを使ってHTTP通信をすることを学んだ。

しかしながらpostメソッドを使う際に情報が不足していたため調べた結果OkHttpの方が使いやすいとわかった。 HttpUrlConnectionは古い事もあってより良く改良されたOkHttpの方がよいと判断した。 下記の記事が参考になりました。ありがとう。

Androidの通信ライブラリの歴史を振り返る

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

OkHttpのインストール

implementation("com.squareup.okhttp3:okhttp:4.3.1")

OkHttp Releases

OkHttpのページには上記の記述があるが、実際のインストールは以下のように実施する。 gradle.appのdependencies{} 内に以下の記述を追加し、右上のsync nowを押す。

implementation  "com.squareup.okhttp3:okhttp:4.3.1"

OkHttpサンプルコード

サンプルコードの内容

  • POST通信
  • メインタスク上でHTTP通信を行う

補足 : アンドロイドのメインタスクで同期通信を行うとエラーが出る。したがってメインタスクではOkHttpでは非同期通信を行わなければならない。

class SignUpActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_up)

        val emailAddress = findViewById<edittext>(R.id.et_emailAddress)
        val password = findViewById<edittext>(R.id.et_password)

        val btn_sendSignUpInfo = findViewById<button>(R.id.btn_sendSignUpInfo)
        btn_sendSignUpInfo.setOnClickListener {


            val client:OkHttpClient = OkHttpClient()
            val url:String = "http://10.0.2.2:8000/api/items/list/"
            val body:FormBody = FormBody.Builder()
                  .add("email", emailAddress)
                  .add("password", password)
                  .build()
            val request = Request.Builder().url(url).post(body).build()

            client.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call?, e: IOException?) {
                    println("fail : $e")
                }

                override fun onResponse(call: Call?, response: Response?) {
                    //ここにレスポンスが返ってきた後の処理を書く。
                    //言わば、AsyncTaskのonPostExecuteメソッドの処理内容を記述する

                    val context = SingletonContext.applicationContext()
                    val intent = Intent(context, ResultTokenActivity::class.java)
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

                    intent.putExtra("result", response!!.body()!!.string())

                    context.startActivity(intent)

        }
    })}}}

補足1 :

POST通信の場合には、bodyオブジェクトを生成し、requestにbodyを追加してHTTP通信してデータを送信する。

OkHttp公式ページのPOSTメソッドレシピ

補足2:

非同期通信を行うには、client.newCall(request).enqueue()を使う。 同期通信の場合にはclient.newCall(request).execute()を実装する。

Responseの内容を取得することについて

まず、非同期処理を行うclient.newCall(request).enque(...中略...)において、リクエストの結果はresponseである。

そしてこのresponseにJSONデータが入っている場合にはprintln(response)としてもJSONデータは表示することができない。

データを表示する場合にはresponseをJSONデータに戻してあげる必要がある。

val json_data = JSONObject(response.body().string())

参考:JSONレスポンスの受け取り方