You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用Geocoder调用getFromLocation遇DEADLINE_EXCEEDED崩溃问题

崩溃原因分析

这个崩溃是因为Geocoder的逆地理编码请求超时,触发了java.io.IOException: DEADLINE_EXCEEDED异常:

  • Geocoder底层依赖系统地理服务(如Google位置服务),当服务在规定时间内无法返回地址结果时,会抛出该超时异常。
  • 部分Android系统版本中,这种IO异常不会被GeocodeListener的onError回调捕获,而是直接向上抛出,导致应用崩溃。
解决办法
  • 捕获IO异常:在调用getFromLocation的代码块外添加try-catch,直接捕获超时或其他IO异常:
try {
    geocoder.getFromLocation(
        latLng.latitude,
        latLng.longitude,
        1,
        object : Geocoder.GeocodeListener {
            override fun onGeocode(addresses: MutableList<Address>) {
                addresses.firstOrNull()?.getAddressLine(0)?.let {
                    onAddressResult(it, null)
                } ?: run {
                    onAddressResult(null, "无可用地址信息")
                }
            }

            override fun onError(errorMessage: String?) {
                onAddressResult(null, errorMessage ?: "未知错误")
            }
        }
    )
} catch (e: IOException) {
    onAddressResult(null, "地址解析超时:${e.message}")
}
  • 提前检查Geocoder可用性:调用getFromLocation前,先通过Geocoder.isPresent()判断设备是否支持地理编码服务,避免无效请求:
if (!Geocoder.isPresent()) {
    onAddressResult(null, "设备不支持地址解析服务")
    return
}
  • 优化地址解析逻辑:避免直接调用addresses.first(),改用firstOrNull()做空安全处理,防止空列表导致的额外崩溃:
override fun onGeocode(addresses: MutableList<Address>) {
    val addressLine = addresses.firstOrNull()?.getAddressLine(0)
    if (addressLine != null) {
        onAddressResult(addressLine, null)
    } else {
        onAddressResult(null, "未解析到有效地址")
    }
}
  • 添加重试机制(可选):针对超时异常,可实现有限次数的重试逻辑(比如最多重试2次),但需设置合理的重试间隔(如1秒),避免频繁请求加重服务负担:
private var retryCount = 0
private fun fetchAddress(latLng: LatLng) {
    if (retryCount >= 2) {
        onAddressResult(null, "多次请求超时,请稍后再试")
        retryCount = 0
        return
    }
    try {
        geocoder.getFromLocation(
            latLng.latitude,
            latLng.longitude,
            1,
            object : Geocoder.GeocodeListener {
                override fun onGeocode(addresses: MutableList<Address>) {
                    addresses.firstOrNull()?.getAddressLine(0)?.let {
                        onAddressResult(it, null)
                    } ?: run {
                        onAddressResult(null, "无可用地址信息")
                    }
                    retryCount = 0
                }

                override fun onError(errorMessage: String?) {
                    if ("DEADLINE_EXCEEDED" in (errorMessage ?: "")) {
                        retryCount++
                        Handler(Looper.getMainLooper()).postDelayed({
                            fetchAddress(latLng)
                        }, 1000)
                    } else {
                        onAddressResult(null, errorMessage)
                        retryCount = 0
                    }
                }
            }
        )
    } catch (e: IOException) {
        if ("DEADLINE_EXCEEDED" in e.message ?: "") {
            retryCount++
            Handler(Looper.getMainLooper()).postDelayed({
                fetchAddress(latLng)
            }, 1000)
        } else {
            onAddressResult(null, e.message)
            retryCount = 0
        }
    }
}

内容的提问来源于stack exchange,提问作者Chandra Shekhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:24:27