Reputation: 1180
l am a beginner in Kotlin. I am using AsyncTask to execute JSON data from an API. I want to add a timeout after a certain period of time in case a user has a very slow or spotty data connection, then show the user an alert dialog, saying, "Sorry you don't have proper internet connectivity" with a button when clicked closes the app.
This is my AsyncTask
code:
inner class Arr : AsyncTask<String, String, String>(){
}
// for build connection
override fun doInBackground(vararg url: String?): String{
var text : String
val connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }
} finally{
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
override fun onProgressUpdate(vararg text: String?) {
}
Upvotes: 3
Views: 870
Reputation: 12148
There are multiple ways to achieve this thing. Two examples are as below :
Adding timeout using HttpURLConnection
:
try {
connection.connectTimeout = 5000 // We all timeout here
connection.connect()
text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }
} finally{
connection.disconnect()
}
Disconnecting manually using Handler
& Runnable
(We can achieve same thing using CountDownTimer or any other stuff too) :
try {
connection.connect()
text = connection.inputStream.use { it.reader().use{reader -> reader.readText()} }
// We all timeout here using Handler
Handler().postDelayed(
{
connection.disconnect() // We disconnect manually
},
5000 // Timeout value
)
} finally{
connection.disconnect()
}
Edit for O.P.:
Use below class for making API call and showing alert to user if connection is timed out.
//We pass context to Activity/Fragment to display alert dialog
inner class TestApiCall(private val context: Context?) : AsyncTask<String, String, String?>() {
// for build connection
override fun doInBackground(vararg url: String?): String? {
var text: String? = null
val connection = URL(url[0]).openConnection() as HttpURLConnection
try {
connection.connect()
text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
handleTimeout { timedOut ->
if (timedOut) {
text = null
connection.disconnect()
print("Timeout Executed")
}
}
} finally {
connection.disconnect()
}
return text
}
private fun handleTimeout(delay: Long = 5000, timeout: (Boolean) -> Unit) {
Handler(Looper.getMainLooper()).postDelayed({
timeout(true)
}, delay)
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
if (result != null) {
//Handle result here
print("Result --> $result")
} else {
//Result is null meaning it can be timed out
context?.let { ctx ->
val alertDialog = AlertDialog.Builder(ctx)
alertDialog.setTitle("Some title here")
alertDialog.setMessage("Notifying user about API error")
alertDialog.create().show()
}
}
}
override fun onProgressUpdate(vararg text: String?) {
//Update progress from here
}
}
Call it from Activity/Fragment
by passing context and "your API URL" :
TestApiCall(context).execute("https://jsonplaceholder.typicode.com/todos/1")
Upvotes: 2