Reputation: 1180
l am try to learn kotlin language , and the first app to me is take data fro json array . but the problem is when start to debug app l got FATAL EXCEPTION: main and app has stopping working . In my Android App, I desgin the following json data construction
my code is :
package com.example.ali.test
import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val url = "https://mysafeinfo.com/api/data?list=presidents&format=json"
Download().execute(url)
}
// full class for json api
inner class Download : AsyncTask<String,String,String>(){
override fun onPreExecute() {
}
// for build connection
override fun doInBackground(vararg p0: String?): String{
try {
val url = URL(p0[0])
val urlConnect = url.openConnection() as HttpURLConnection
urlConnect.connectTimeout = 700
val inputStream = urlConnect.inputStream
val dataJsonAsStr = covertStreamToString(urlConnect.inputStream)
publishProgress(dataJsonAsStr)
} catch (e: Exception){
}
return ""
}
// for get items from json api
override fun onProgressUpdate(vararg values: String?) {
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
}
fun handleJson (jsonString: String?){
val jsonArray = JSONArray(jsonString)
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(x)
list.add(FlightShdu(
jsonObject.getInt("id"),
jsonObject.getString("nm")
))
x++
}
val adapter = ListAdapte(this@MainActivity,list)
flightShdu_list.adapter = adapter
}
// for connection api
fun covertStreamToString (inputStream: InputStream): String {
val bufferReader = BufferedReader(InputStreamReader(inputStream))
var line:String
var allString:String=""
try {
do{
line=bufferReader.readLine()
if (line!=null)
allString+=line
}while (line!=null)
bufferReader.close()
}catch (ex:java.lang.Exception){}
return allString;
}
}
error in console :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ali.test, PID: 24738
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: org.json.JSONException: End of input at character 0 of
at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
at org.json.JSONTokener.nextValue(JSONTokener.java:97)
at org.json.JSONArray.<init>(JSONArray.java:92)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.example.ali.test.MainActivity.handleJson(MainActivity.kt:68)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:59)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:27)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
any one have any idea please ?
Upvotes: 0
Views: 170
Reputation: 1052
**
Use your code like this example below:
**
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val s = tvDisplay.text.toString()
btnOk.setOnClickListener {
Download().execute(s)
}
}
inner class Download : AsyncTask<String, Void, Void>() {
override fun doInBackground(vararg ss: String?): Void? {
validate(ss[0]!!)
return null
}
}
private fun validate(s:String) {
if(s.isNotEmpty()){
runOnUiThread {
Toast.makeText(this, "Working :)", Toast.LENGTH_SHORT).show()
}
}
else{
runOnUiThread {
Toast.makeText(this, "Not Working :(", Toast.LENGTH_SHORT).show()
}
}
}
}
Upvotes: 0
Reputation: 511
Your doInBackground()
always returns an empty string, ""
. This empty string will be passed as the parameter to onPostExecute
, which in turns uses this empty string as a parameter to handleJson
. When you try to create a JSON array from this empty string it throws an exception at index 0, as it doesn't have any more data and it's not a valid json.
You need to return the result of the network call from doInBackground()
instead of an empty string.
Upvotes: 1