已弃用的导入 android.os.AsyncTask 代码



我一直在编写一些代码,它给了我一个错误,指出异步函数已被弃用。 我正在尝试解决此问题,但我迷失了哪种方法是解决此问题的最佳方法。请告知是否有针对该代码的解决方法。我正在从开放天气图中提取数据以供 5 月应用程序使用。

import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import org.json.JSONObject
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity() {
val LAT: String = "1.4854081"
val LON: String = "14.6618699"
val API: String = "API FROM OPEN WEATHER REMOVED"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
weatherTask().execute()
}
inner class weatherTask() : AsyncTask<String, Void, String>() {
override fun onPreExecute() {
super.onPreExecute()
/* Showing the ProgressBar, Making the main design GONE */
findViewById<ProgressBar>(R.id.loader).visibility = View.VISIBLE
findViewById<RelativeLayout>(R.id.mainContainer).visibility = View.GONE
findViewById<TextView>(R.id.errorText).visibility = View.GONE
}
override fun doInBackground(vararg params: String?): String? {
var response:String?
try{
response = URL("https://api.openweathermap.org/data/2.5/weather?lat=$LAT&lon=$LON&units=metric&appid=$API").readText(
Charsets.UTF_8
)
}catch (e: Exception){
response = null
}
return response
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
try {
/* Extracting JSON returns from the API */
val jsonObj = JSONObject(result)
val main = jsonObj.getJSONObject("main")
val sys = jsonObj.getJSONObject("sys")
val wind = jsonObj.getJSONObject("wind")
val weather = jsonObj.getJSONArray("weather").getJSONObject(0)
val updatedAt:Long = jsonObj.getLong("dt")
val updatedAtText = "Updated at: "+ SimpleDateFormat("dd/MM/yyyy hh:mm a", Locale.ENGLISH).format(Date(updatedAt*1000))
val temp = main.getString("temp")+"°C"
val tempMin = "Min Temp: " + main.getString("temp_min")+"°C"
val tempMax = "Max Temp: " + main.getString("temp_max")+"°C"
val pressure = main.getString("pressure")
val humidity = main.getString("humidity")
val sunrise:Long = sys.getLong("sunrise")
val sunset:Long = sys.getLong("sunset")
val windSpeed = wind.getString("speed")
val weatherDescription = weather.getString("description")
val address = jsonObj.getString("name")+", "+sys.getString("country")
/* Populating extracted data into our views */
findViewById<TextView>(R.id.address).text = address
findViewById<TextView>(R.id.updated_at).text =  updatedAtText
findViewById<TextView>(R.id.status).text = weatherDescription.capitalize()
findViewById<TextView>(R.id.temp).text = temp
findViewById<TextView>(R.id.temp_min).text = tempMin
findViewById<TextView>(R.id.temp_max).text = tempMax
findViewById<TextView>(R.id.sunrise).text = SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(Date(sunrise*1000))
findViewById<TextView>(R.id.sunset).text = SimpleDateFormat("hh:mm a", Locale.ENGLISH).format(Date(sunset*1000))
findViewById<TextView>(R.id.wind).text = windSpeed
findViewById<TextView>(R.id.pressure).text = pressure
findViewById<TextView>(R.id.humidity).text = humidity
/* Views populated, Hiding the loader, Showing the main design */
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<RelativeLayout>(R.id.mainContainer).visibility = View.VISIBLE
} catch (e: Exception) {
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<TextView>(R.id.errorText).visibility = View.VISIBLE
}
}
}
}

您可以使用 Kotlin 协程实现类似于AsyncTask的东西:

class AsyncTaskViewModel : ViewModel() {

fun <R> execute(
onPreExecute: () -> Unit,
doInBackground: () -> R,
onPostExecute: (R) -> Unit
) = viewModelScope.launch {
onPreExecute()
val result = withContext(Dispatchers.IO) { // runs in background thread without blocking the Main Thread
doInBackground()
}
onPostExecute(result)
}
}

在检索AsyncTaskViewModelActivity

val vm: AsyncTaskViewModel by lazy { ViewModelProvider(this)[AsyncTaskViewModel::class.java] }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vm.execute(onPreExecute = {
//...
}, doInBackground = {
//...
"Response" // value to return
}, onPostExecute = {
// ... here "it" contains data returned from "doInBackground"
})
}

如果你不想使用ViewModel,只需在CoroutineScope上创建一个扩展函数并从Activity调用它:

// extension function:
fun <R> CoroutineScope.executeAsyncTask(
onPreExecute: () -> Unit,
doInBackground: () -> R,
onPostExecute: (R) -> Unit
) = launch {
onPreExecute()
val result = withContext(Dispatchers.IO) { // runs in background thread without blocking the Main Thread
doInBackground()
}
onPostExecute(result)
}

// Call it from Activity: 
lifecycleScope.executeAsyncTask(onPreExecute = {
// ...
}, doInBackground = {
//...
"Response" // value to return
}, onPostExecute = {
// ... here "it" contains data returned from "doInBackground"
})

要使用viewModelScopelifecycleScope将下一行添加到应用的build.gradle文件的依赖项中,请执行以下操作:

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION" // for viewModelScope
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$LIFECYCLE_VERSION" // for lifecycleScope

最新更新