Android 11中AsyncTask已废弃,如何用java.util.concurrent替换Kotlin代码?
Android 11废弃AsyncTask后,Kotlin中的替代方案及代码迁移示例
Google在Android 11中正式废弃了AsyncTask API,官方推荐使用java.util.concurrent包下的工具类来替代。下面针对你提供的AsyncTask代码,给出具体的迁移方案,同时补充Kotlin中更常用的协程方案。
一、使用java.util.concurrent的迁移实现
原AsyncTask的核心逻辑是后台执行网络请求,主线程解析数据并更新Google Map,我们可以用ExecutorService执行后台任务,配合Handler切回主线程更新UI,具体代码如下:
package gaspriceinegypt.gaspriceegypt.gaspriceinegypt import android.os.Handler import android.os.Looper import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.model.CameraUpdateFactory import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.io.IOException import java.util.concurrent.Executors class FetchPlacesData(private val googleMap: GoogleMap) { // 创建单线程线程池,适配单个后台任务场景 private val executor = Executors.newSingleThreadExecutor() // 获取主线程Handler,用于切换线程更新UI private val mainHandler = Handler(Looper.getMainLooper()) fun fetchData(url: String) { executor.execute { var response: String? = null try { val downloadUrl = DownloadUrl() response = downloadUrl.retireveUrl(url) } catch (e: IOException) { e.printStackTrace() } // 切回主线程处理解析和UI更新 mainHandler.post { response?.let { parseAndUpdateMap(it) } } } } private fun parseAndUpdateMap(response: String) { try { val jsonObject = JSONObject(response) val jsonArray = jsonObject.getJSONArray("results") for (i in 0 until jsonArray.length()) { val jsonObject1 = jsonArray.getJSONObject(i) val locationObj = jsonObject1.getJSONObject("geometry").getJSONObject("location") val lat = locationObj.getString("lat").toDouble() val lng = locationObj.getString("lng").toDouble() val name = jsonObject1.getString("name") val latLng = LatLng(lat, lng) val markerOptions = MarkerOptions().title(name).position(latLng) googleMap.addMarker(markerOptions) googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f)) } } catch (e: JSONException) { e.printStackTrace() } } // 在页面销毁时关闭线程池,避免内存泄漏 fun shutdown() { executor.shutdown() } }
使用方式
在Activity/Fragment中调用:
// 假设已获取GoogleMap实例 val fetchPlacesData = FetchPlacesData(googleMap) fetchPlacesData.fetchData("你的请求URL") // 在Activity的onDestroy中释放资源 override fun onDestroy() { super.onDestroy() fetchPlacesData.shutdown() }
二、Kotlin更推荐的协程方案
除了java.util.concurrent,Kotlin的协程(Coroutines)写法更简洁,无需手动管理线程池,是Android开发中异步任务的首选方案:
package gaspriceinegypt.gaspriceegypt.gaspriceinegypt import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.model.CameraUpdateFactory import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.io.IOException class FetchPlacesData(private val googleMap: GoogleMap) { fun fetchData(url: String) { GlobalScope.launch(Dispatchers.IO) { var response: String? = null try { val downloadUrl = DownloadUrl() response = downloadUrl.retireveUrl(url) } catch (e: IOException) { e.printStackTrace() } response?.let { // 切回主线程处理UI更新 withContext(Dispatchers.Main) { parseAndUpdateMap(it) } } } } private fun parseAndUpdateMap(response: String) { try { val jsonObject = JSONObject(response) val jsonArray = jsonObject.getJSONArray("results") for (i in 0 until jsonArray.length()) { val jsonObject1 = jsonArray.getJSONObject(i) val locationObj = jsonObject1.getJSONObject("geometry").getJSONObject("location") val lat = locationObj.getString("lat").toDouble() val lng = locationObj.getString("lng").toDouble() val name = jsonObject1.getString("name") val latLng = LatLng(lat, lng) val markerOptions = MarkerOptions().title(name).position(latLng) googleMap.addMarker(markerOptions) googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f)) } } catch (e: JSONException) { e.printStackTrace() } } }
使用方式
直接在Activity/Fragment中调用即可,协程会自动管理线程:
val fetchPlacesData = FetchPlacesData(googleMap) fetchPlacesData.fetchData("你的请求URL")
内容的提问来源于stack exchange,提问作者Ahmed Hossam
相关产品推荐
相关产品推荐

