不推荐使用的导入 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"
)

要使用viewModelScopelifecycleScope,请在应用的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

用C#将一个EXCEL导入到DATASET中,但是读出来的时候发现有些数据没有导入,不同的EXCEL情况也不一样

matplotlib基本绘图参数

Eclipse 工程迁移到 Android Studio

Eclipse 工程迁移到 Android Studio

Eclipse 工程迁移到 Android Studio