不推荐使用的导入 android.os.AsyncTask 的代码 [重复]
Posted
技术标签:
【中文标题】不推荐使用的导入 android.os.AsyncTask 的代码 [重复]【英文标题】:Deprecated code for import android.os.AsyncTask [duplicate] 【发布时间】:2020-10-13 22:00:30 【问题描述】:我一直在编写一些代码,它给了我一个错误,指出 Async 函数已被弃用。 我正在尝试解决此问题,但我不知道哪种方法是解决此问题的最佳方法。请告知是否有代码的解决方法。我正在为可能的应用程序从开放天气地图中提取数据。
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
【问题讨论】:
这可能有助于***.com/a/58900195/1731626 【参考方案1】:您可以使用 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)
在Activity
中检索AsyncTaskViewModel
:
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"
)
要使用viewModelScope
和lifecycleScope
,请在应用的build.gradle 文件的依赖项中添加下一行:
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION" // for viewModelScope
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$LIFECYCLE_VERSION" // for lifecycleScope
【讨论】:
以上是关于不推荐使用的导入 android.os.AsyncTask 的代码 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用 React native 不推荐使用 AsyncStorage