Kotlin入门开发者:如何为AsyncTask添加超时并处理网络异常
Hey there! Let's fix up your AsyncTask to handle slow/unstable networks with a timeout, and show that friendly error dialog when things go wrong. Here's how to do it step by step:
1. Add Timeout Settings to Your HttpURLConnection
First, we'll set connect timeout (time to wait for the connection to establish) and read timeout (time to wait for data to come through) on your HttpURLConnection. I'll use 10 seconds as an example, but you can adjust this to fit your needs.
2. Handle Timeout & Network Exceptions
We'll catch SocketTimeoutException (for timeouts) and general IOException (for other network issues) in the doInBackground method. When an exception occurs, we'll return null to signal an error.
3. Show Error Dialog in onPostExecute
In onPostExecute, we'll check if the result is null (meaning a network error/timeout happened). If so, we'll display your desired alert dialog, and close the app when the user taps the button.
Modified AsyncTask Code
Here's your updated Arr AsyncTask with all these changes:
inner class Arr : AsyncTask<String, String, String?>() { // Change return type to String? to allow null override fun doInBackground(vararg url: String?): String? { val targetUrl = url[0] ?: return null // Handle null input URL var text: String? = null var connection: HttpURLConnection? = null try { connection = URL(targetUrl).openConnection() as HttpURLConnection // Set timeouts (10 seconds each - adjust as needed) connection.connectTimeout = 10000 connection.readTimeout = 10000 connection.connect() // Read the response safely with use() (auto-closes streams) text = connection.inputStream.use { inputStream -> inputStream.reader().use { reader -> reader.readText() } } } catch (e: SocketTimeoutException) { // Triggered when connection or read takes too long e.printStackTrace() } catch (e: IOException) { // Covers other network issues (no internet, invalid URL, etc.) e.printStackTrace() } finally { connection?.disconnect() // Safely disconnect regardless of success/failure } return text } override fun onPostExecute(result: String?) { super.onPostExecute(result) if (result == null) { // Network error/timeout occurred - show dialog showNetworkErrorDialog() } else { // Success - process your JSON handleJson(result) } } override fun onProgressUpdate(vararg text: String?) { // Keep your existing progress update logic here if needed } private fun showNetworkErrorDialog() { AlertDialog.Builder(this@YourActivityName) // Replace with your actual activity name (e.g., this@MainActivity) .setTitle("Network Issue") .setMessage("Sorry you don't have proper internet connectivity") .setPositiveButton("Close App") { _, _ -> // Close the app properly finishAffinity() // Closes all activities in the app's stack System.exit(0) // Ensures the app process is terminated } .setCancelable(false) // Prevent user from dismissing the dialog by tapping outside .show() } }
Key Notes:
- Nullable Return Type: We updated the AsyncTask's generic return type to
String?so we can returnnullwhen an error occurs, making it easy to detect failures inonPostExecute. - Timeout Values:
connectTimeoutandreadTimeoutare set in milliseconds. Tweak10000(10 seconds) to match your app's needs. - Safe Stream Handling: We use
use()for streams and readers, which automatically closes them when done—no need to manually manage close calls. - Dialog Behavior: The error dialog can't be canceled, and the "Close App" button ensures the entire app shuts down cleanly.
- Activity Reference: Don't forget to replace
this@YourActivityNamewith the actual name of your activity (likethis@MainActivity).
Quick Heads-Up About AsyncTask
Just a friendly reminder: AsyncTask is deprecated in Android API level 30. For future projects, consider using modern alternatives like Kotlin Coroutines, Volley, or Retrofit for network operations. But since you're just starting out with Kotlin, this solution will work perfectly for your current setup!
内容的提问来源于stack exchange,提问作者Ali Ghassan

