kotlinでandroid開発を勉強している初心者です。
書籍を参考にhttp通信を用いてlivedoorから天気情報を取得して表示させたいのですが、実行してみると繰り返し停止しますというエラーが出て強制終了してしまいます。以下がエラーが出るMainActivity.ktのコードです。実行は実機で、Galaxy S9です。
エラー内容はListItemClickLister内に二つ、WeatherInfoReceiver内に一つで、コメントとして書きました。ご回答よろしくお願いします。
Kotlin
1package com.example.asynksample 2 3import android.os.AsyncTask 4import androidx.appcompat.app.AppCompatActivity 5import android.os.Bundle 6import android.view.View 7import android.widget.AdapterView 8import android.widget.ListView 9import android.widget.SimpleAdapter 10import android.widget.TextView 11import org.json.JSONObject 12import java.io.BufferedReader 13import java.io.InputStream 14import java.io.InputStreamReader 15import java.net.HttpURLConnection 16import java.net.URL 17 18class MainActivity : AppCompatActivity() { 19 20 override fun onCreate(savedInstanceState: Bundle?) { 21 super.onCreate(savedInstanceState) 22 setContentView(R.layout.activity_main) 23 24 //画面部品ListViewを取得 25 val lvCityList = findViewById<ListView>(R.id.lvCityList) 26 //SimpleAdapterで使用するMutableListオブジェクトを用意 27 val cityList: MutableList<MutableMap<String, String>> = mutableListOf() 28 //都市データを格納するMutableMapオブジェクトの用意とcityListへのデータ登録 29 val city = mutableMapOf("name" to "東京","id" to "130010") 30 cityList.add(city) 31 //SimpleAdapterで使用するfrom-to用変数の用意 32 val from = arrayOf("name") 33 val to = intArrayOf(android.R.id.text1) 34 //SimpleAdapterを生成 35 val adapter = SimpleAdapter(applicationContext, cityList, android.R.layout.simple_expandable_list_item_1, from, to) 36 //ListViewにSimpleAdapterを設定 37 lvCityList.adapter = adapter 38 //リストタップのリスナクラス登録 39 lvCityList.onItemClickListener = ListItemClickListener() 40 } 41 42 //リストがタップされたときの処理が記述されたメンバクラス 43 private inner class ListItemClickListener : AdapterView.OnItemClickListener { 44 override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { 45 //ListViewでタップされた行の都市名と都市IDを取得 46 val item = parent.getItemAtPosition(position) as Map<String,String> //(警告)Unchecked cast: Any! to Map<String, String> 47 val cityName = item["name"] 48 val cityId = item["id"] 49 //取得した都市名をtvCityNameに設定 50 val tvCityName = findViewById<TextView>(R.id.tvCityName) 51 tvCityName.setText(cityName + "の天気:") //エラー: Use of setter method insted of property access syntax 52 //WeatherInfoReceiverインスタンスを生成 53 val receiver = WeatherInfoReceiver() 54 //WeatherInfoReceiverを実行 55 receiver.execute(cityId) 56 } 57 } 58 59 private inner class WeatherInfoReceiver : AsyncTask<String, String, String>() { //(警告)This AsyncTask class should be static or leaks might occur 60 override fun doInBackground(vararg params: String): String { 61 //可変長引数の1個目(インデックス0)を取得。これが都市ID 62 val id = params[0] 63 //都市IDを使って接続URL文字列を作成 64 val urlStr = "http://weather.livedoor.com/forecast/webservise/json/v1?city=${id}" 65 66 //ここに上記URLに接続してJSON文字列を取得する処理を記述 67 //URLオブジェクトを生成 68 val url = URL(urlStr) 69 //URLオブジェクトからHttpURLConnectionオブジェクトを取得 70 val con = url.openConnection() as HttpURLConnection 71 //http接続メソッドを設定 72 con.requestMethod = "GET" 73 //接続 74 con.connect() 75 //HttpURLConnectionオブジェクトからレスポンスデータを取得。天気情報が格納されている 76 val stream = con.inputStream 77 //レスポンスデータであるInputStreamオブジェクトを文字列(JSON文字列)に変換 78 val result = is2String(stream) 79 //HttpURLConnectionオブジェクトを解放 80 con.disconnect() 81 //InputStreamオブジェクトを開放 82 stream.close() 83 84 //JSON文字列を返す 85 return result 86 } 87 88 override fun onPostExecute(result: String) { 89 90 //ここに天気情報JSON文字列を解析する処理を記述 91 //JSON文字列からJSONObjectオブジェクトを生成。これをルートJSONオブジェクトとする 92 val rootJSON = JSONObject(result) 93 //ルートJSON直下の「description」JSONオブジェクトを取得 94 val descriptionJSON = rootJSON.getJSONObject("description") 95 //「description」プロパティ直下の「text」文字列(天気概況文)を取得 96 val desc = descriptionJSON.getString("text") 97 //ルートJSON直下の「forecasts」JSON配列を取得 98 val forecasts = rootJSON.getJSONArray("forecasts") 99 //「forecasts」JSON配列の一つ目(インデックス0)のJSONオブジェクトを取得 100 val forecastNow = forecasts.getJSONObject(0) 101 //「forecasts」一つ目のJSONオブジェクトから「telop」文字列(天気)を取得 102 val telop = forecastNow.getString("telop") 103 104 //天気情報用文字列をTextViewにセット 105 val tvWeatherTelop = findViewById<TextView>(R.id.tvWeatherTelop) 106 val tvWeatherDesc = findViewById<TextView>(R.id.tvWeatherDesc) 107 tvWeatherTelop.text = telop 108 tvWeatherDesc.text = desc 109 } 110 111 private fun is2String(stream: InputStream): String { 112 val sb = StringBuilder() 113 val reader = BufferedReader(InputStreamReader(stream, "UTF-8")) 114 var line = reader.readLine() 115 while(line !=null) { 116 sb.append(line) 117 line = reader.readLine() 118 } 119 reader.close() 120 return sb.toString() 121 } 122 } 123} 124
回答1件
あなたの回答
tips
プレビュー