facebook twitter hatena line email

「Android/kotlin/http通信」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(asyncでアクセス)
(コールチンのExceptionについて)
 
(同じ利用者による、間の10版が非表示)
行7: 行7:
 
<pre>
 
<pre>
 
class HttpRequest {
 
class HttpRequest {
 +
    private var status = 0;
 
     private var body = "";
 
     private var body = "";
 
     fun request(requestUrl: String): Boolean {
 
     fun request(requestUrl: String): Boolean {
行17: 行18:
 
         urlConnection.requestMethod = "GET"
 
         urlConnection.requestMethod = "GET"
 
         urlConnection.connect()
 
         urlConnection.connect()
 +
        status = urlConnection.responseCode
 
         val br = BufferedReader(InputStreamReader(urlConnection.inputStream))
 
         val br = BufferedReader(InputStreamReader(urlConnection.inputStream))
 
         val sb = StringBuilder()
 
         val sb = StringBuilder()
行28: 行30:
 
     fun getBody(): String {
 
     fun getBody(): String {
 
         return body
 
         return body
 +
    }
 +
    fun getStatusCode(): Int {
 +
        return status
 
     }
 
     }
 
     companion object {
 
     companion object {
行36: 行41:
 
参考:https://qiita.com/naoi/items/8df1409ad48ad8f3c632
 
参考:https://qiita.com/naoi/items/8df1409ad48ad8f3c632
  
==asyncでアクセス==
+
==AsyncTsnkでアクセス==
 
直アクセスだとアクセスできないのでAsyncTaskをかます。
 
直アクセスだとアクセスできないのでAsyncTaskをかます。
  
行60: 行65:
 
         super.onPostExecute(flag)
 
         super.onPostExecute(flag)
 
     }
 
     }
 +
}
 +
</pre>
 +
 +
===AsyncTsnkでException===
 +
doInBackground内でExceptionは使えない。cancel(true)などを使えば、onCancelledが呼ばれるのでそのようにする。
 +
<pre>
 +
    override fun doInBackground(vararg p: Void?): Boolean {
 +
        throw Exception("error")
 +
        // cancel(true)
 +
        return true
 +
    }
 +
    override fun onCancelled(flag: Boolean) {
 +
        super.onCancelled(flag)
 +
    }
 +
</pre>
 +
<pre>
 +
        try {
 +
            var task = HttpAsyncTask()
 +
            task.execute()
 +
        } catch (e: Exception) {
 +
            Log.e("test", "HttpAsyncTask ${e.message}")
 +
        }
 +
</pre>
 +
 +
==コールチンでアクセス==
 +
AsyncTaskの代わりにkotlin1.3より公式となったコールチンでもアクセスできます。
 +
 +
準備
 +
 +
app/build.gradle
 +
<pre>
 +
dependencies {
 +
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
 +
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
 +
}
 +
</pre>
 +
 +
 +
MainActivity.kt
 +
<pre>
 +
import androidx.appcompat.app.AppCompatActivity
 +
import android.os.Bundle
 +
import android.util.Log
 +
import kotlinx.android.synthetic.main.activity_main.*
 +
import kotlinx.coroutines.CoroutineScope
 +
import kotlinx.coroutines.Dispatchers
 +
import kotlinx.coroutines.launch
 +
import kotlinx.coroutines.withContext
 +
 +
class MainActivity : AppCompatActivity() {
 +
    val scope = CoroutineScope(Dispatchers.Default)
 +
    override fun onCreate(savedInstanceState: Bundle?) {
 +
        super.onCreate(savedInstanceState)
 +
        setContentView(R.layout.activity_main)
 +
        scope.launch {
 +
            httpTask()
 +
        }
 +
    }
 +
    private suspend fun httpTask() {
 +
        try {
 +
            withContext(Dispatchers.Main) {
 +
                Log.i(localClassName, "onPreExecute")
 +
            }
 +
            var httpRequest = HttpRequest()
 +
            //var http = HttpUtil()
 +
            var success: Boolean = httpRequest.request("https://h2ch.com/?hogehoge")
 +
            Log.i(localClassName, "body=" + httpRequest.getBody())
 +
            Log.i(localClassName, "status=" + httpRequest.getStatusCode().toString())
 +
 +
            withContext(Dispatchers.Main) {
 +
                Log.i(localClassName, "onPostExecute")
 +
            }
 +
        } catch (e: Exception) {
 +
            Log.e(localClassName, "onCancelled", e)
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 +
コルーチンから呼び出すメソッドはsuspend修飾子が必要。
 +
 +
===コールチンのExceptionについて===
 +
以下はできるが、
 +
<pre>
 +
private suspend fun httpTask() {
 +
    try {
 +
        throw Exception("damedesu")
 +
    } catch (e: Exception) {
 +
        Log.e(localClassName, "onCancelled", e)
 +
    }
 +
}
 +
</pre>
 +
以下はできない。
 +
<pre>
 +
try {
 +
    scope.launch {
 +
        httpTask()
 +
    }
 +
} catch (e: Exception) {
 +
    Log.e(localClassName, "onCancelled", e)
 +
}
 +
private suspend fun httpTask() {
 +
    throw Exception("damedesu")
 
}
 
}
 
</pre>
 
</pre>

2020年3月23日 (月) 15:28時点における最新版

準備

AndroidManifext.xmlに以下を追加しておく。

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

サンプル

HttpRequest.kt

class HttpRequest {
    private var status = 0;
    private var body = "";
    fun request(requestUrl: String): Boolean {
        if (requestUrl.isEmpty()) {
            Log.w(TAG, "URLが空です。")
            return false
        }
        val url = URL(requestUrl)
        val urlConnection = url.openConnection() as HttpURLConnection
        urlConnection.requestMethod = "GET"
        urlConnection.connect()
        status = urlConnection.responseCode
        val br = BufferedReader(InputStreamReader(urlConnection.inputStream))
        val sb = StringBuilder()
        for (line: String? in br.readLines()) {
            line?.let { sb.append(line) }
        }
        br.close()
        body = sb.toString()
        return true
    }
    fun getBody(): String {
        return body
    }
    fun getStatusCode(): Int {
        return status
    }
    companion object {
        private const val TAG = "HttpRequest"
    }
}

参考:https://qiita.com/naoi/items/8df1409ad48ad8f3c632

AsyncTsnkでアクセス

直アクセスだとアクセスできないのでAsyncTaskをかます。

起動方法

var task = HttpAsyncTask();
task.execute();

HttpAsyncTask.kt

import android.os.AsyncTask
class HttpAsyncTask : AsyncTask<Void, Void, Boolean>() {
    override fun onPreExecute() {
        Log.i(TAG, "onPreExecute")
    }
    override fun doInBackground(vararg p: Void?): Boolean {
        var httpRequest = HttpRequest()
        var success: Boolean = httpRequest.request("https://example.com/?hogehoge")
        Log.i(TAG, "body=" + httpRequest.getBody())
        return true
    }
    override fun onPostExecute(flag: Boolean) {
        Log.i(TAG, "onPostExecute flag=" + flag)
        super.onPostExecute(flag)
    }
}

AsyncTsnkでException

doInBackground内でExceptionは使えない。cancel(true)などを使えば、onCancelledが呼ばれるのでそのようにする。

    override fun doInBackground(vararg p: Void?): Boolean {
        throw Exception("error")
        // cancel(true)
        return true
    }
    override fun onCancelled(flag: Boolean) {
        super.onCancelled(flag)
    }
        try {
            var task = HttpAsyncTask()
            task.execute()
        } catch (e: Exception) {
            Log.e("test", "HttpAsyncTask ${e.message}")
        }

コールチンでアクセス

AsyncTaskの代わりにkotlin1.3より公式となったコールチンでもアクセスできます。

準備

app/build.gradle

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
}


MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MainActivity : AppCompatActivity() {
    val scope = CoroutineScope(Dispatchers.Default)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        scope.launch {
            httpTask()
        }
    }
    private suspend fun httpTask() {
        try {
            withContext(Dispatchers.Main) {
                Log.i(localClassName, "onPreExecute")
            }
            var httpRequest = HttpRequest()
            //var http = HttpUtil()
            var success: Boolean = httpRequest.request("https://h2ch.com/?hogehoge")
            Log.i(localClassName, "body=" + httpRequest.getBody())
            Log.i(localClassName, "status=" + httpRequest.getStatusCode().toString())

            withContext(Dispatchers.Main) {
                Log.i(localClassName, "onPostExecute")
            }
        } catch (e: Exception) {
            Log.e(localClassName, "onCancelled", e)
        }
    }
}

コルーチンから呼び出すメソッドはsuspend修飾子が必要。

コールチンのExceptionについて

以下はできるが、

private suspend fun httpTask() {
    try {
        throw Exception("damedesu")
    } catch (e: Exception) {
        Log.e(localClassName, "onCancelled", e)
    }
}

以下はできない。

try {
    scope.launch {
        httpTask()
    }
} catch (e: Exception) {
    Log.e(localClassName, "onCancelled", e)
}
private suspend fun httpTask() {
    throw Exception("damedesu")
}