「Android/kotlin/http通信」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→コールチンのExceptionについて) |
|||
(同じ利用者による、間の20版が非表示) | |||
行1: | 行1: | ||
+ | ==準備== | ||
+ | AndroidManifext.xmlに以下を追加しておく。 | ||
+ | <uses-permission android:name="android.permission.INTERNET" /> | ||
+ | |||
==サンプル== | ==サンプル== | ||
HttpRequest.kt | HttpRequest.kt | ||
<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 { | ||
行13: | 行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() | ||
行24: | 行30: | ||
fun getBody(): String { | fun getBody(): String { | ||
return body | return body | ||
+ | } | ||
+ | fun getStatusCode(): Int { | ||
+ | return status | ||
} | } | ||
companion object { | companion object { | ||
行32: | 行41: | ||
参考:https://qiita.com/naoi/items/8df1409ad48ad8f3c632 | 参考:https://qiita.com/naoi/items/8df1409ad48ad8f3c632 | ||
− | == | + | ==AsyncTsnkでアクセス== |
+ | 直アクセスだとアクセスできないのでAsyncTaskをかます。 | ||
+ | |||
+ | 起動方法 | ||
+ | var task = HttpAsyncTask(); | ||
+ | task.execute(); | ||
+ | |||
HttpAsyncTask.kt | HttpAsyncTask.kt | ||
<pre> | <pre> | ||
import android.os.AsyncTask | import android.os.AsyncTask | ||
class HttpAsyncTask : AsyncTask<Void, Void, Boolean>() { | class HttpAsyncTask : AsyncTask<Void, Void, Boolean>() { | ||
− | + | override fun onPreExecute() { | |
+ | Log.i(TAG, "onPreExecute") | ||
+ | } | ||
override fun doInBackground(vararg p: Void?): Boolean { | override fun doInBackground(vararg p: Void?): Boolean { | ||
var httpRequest = HttpRequest() | var httpRequest = HttpRequest() | ||
− | + | var success: Boolean = httpRequest.request("https://example.com/?hogehoge") | |
− | var success = httpRequest.request("https:// | + | |
Log.i(TAG, "body=" + httpRequest.getBody()) | Log.i(TAG, "body=" + httpRequest.getBody()) | ||
− | return | + | return true |
} | } | ||
− | override fun onPostExecute( | + | override fun onPostExecute(flag: Boolean) { |
− | super.onPostExecute( | + | Log.i(TAG, "onPostExecute flag=" + 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") }