環境
やりたいこと
URL指定したらHTTPリクエストしてデータを取得、表示まで
基礎を学ぶ用なので必要最低限のコードのみ
ライブラリの追加
自分でゴリゴリHttpURLConnection書くのはツラみがあるのでokhttpというライブラリを使う。
元々JavaのライブラリだがKotlinにも対応しているので問題ない。古いQiitaの記事とかだと未対応だから~って書いてあるが。
build.gradleのdependencies項目に以下を追記 これだけ
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
(略)
compile 'com.squareup.okhttp3:okhttp:3.10.0'
}
コード
先にMainActivityにid=mytextのテキストビューを追加しておく
外部からデータを取得するメソッド ふつうはJSONとかだが、サンプルとしてここではGoogleのサイトを取得している
class MainActivity : AppCompatActivity() {
(略)
}
fun getHtml(): String {
val client = OkHttpClient()
val req = Request.Builder().url("http://google.com").get().build()
val resp = client.newCall(req).execute()
return resp.body()!!.string()
}
次にパーミッション。AndroidManifest.xmlに<uses-permission android:name="android.permission.INTERNET" />
を追加
xml version="1.0" encoding="utf-8"
<manifest xmlnsandroid="http://schemas.android.com/apk/res/android"
package="com.example.user.fetchsample">
<application>
(略)
</application>
<uses-permission androidname="android.permission.INTERNET" />
</manifest>
でメインの処理を書く。が、以下は動きそうで動かない ネットワーク通信はメインスレッドで行っていけなく、非同期通信しなければならない。(android.os.NetworkOnMainThreadExceptionが発生する)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tview = findViewById<TextView>(R.id.mytext)
val result = getHtml()
tview.setText(result)
仕方ないのでAsyncTaskを使う。AsyncTaskクラスを継承したMyAsyncTaskをMainActivityクラス内に記述。doInBackground()は非同期で行いたい処理の内容、onPostExecute()はdoInBackground()終了後にメインスレッドで実行される処理の内容である
inner class MyAsyncTask: AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg p0: Void?): String? {
return getHtml()
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
val tview = findViewById<TextView>(R.id.mytext)
tview.setText(result)
}
}
で以下で非同期処理が実行される
MyAsyncTask().execute()
ソース全体は以下
package com.example.user.fetchsample
import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import okhttp3.OkHttpClient
import okhttp3.Request
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyAsyncTask().execute()
}
inner class MyAsyncTask: AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg p0: Void?): String? {
return getHtml()
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
val tview = findViewById<TextView>(R.id.mytext)
tview.setText(result)
}
}
}
fun getHtml(): String {
val client = OkHttpClient()
val req = Request.Builder().url("http://google.com").get().build()
val resp = client.newCall(req).execute()
return resp.body()!!.string()
}
サンプルとはいえgetHtml()がグローバルなところにいるのはいかがなものかと思いつつ、今日は眠いのでここまで
参考リンク