Kotlin开发中fetchLocation()本地变量无法传递到callAPI()如何解决
问题根源
fusedLocationProviderClient.lastLocation 是异步操作,你在 onViewCreated 里顺序调用 fetchLocation() 和 callAPI() 时,位置请求的成功回调还没执行,全局变量q还保持初始空值,所以调用接口会报错。
解决方案:在位置获取成功回调中触发接口请求
直接把callAPI()的调用移到addOnSuccessListener回调里,保证只有拿到经纬度之后再调用接口,同时优化原有代码的稳定性问题:
class BlankFragment : Fragment() { lateinit var fusedLocationProviderClient: FusedLocationProviderClient private val key = "5a812faf9e1e4a66b17223056210911" private val days = 1 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireActivity()) fetchLocation() // 移除此处的callAPI()调用 } private fun fetchLocation() { // 用ContextCompat检查权限,requireContext避免空指针 if (ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { // 用Fragment原生申请权限方法,回调会走当前Fragment的onRequestPermissionsResult requestPermissions(arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), 101) return } val task = fusedLocationProviderClient.lastLocation task.addOnSuccessListener { location -> location?.let { val q = "${it.latitude},${it.longitude}" // 拿到经纬度后再调用接口 callAPI(q) } ?: run { // 位置获取为空处理,比如提示用户开启定位、默认填城市名 Toast.makeText(requireContext(), "无法获取当前位置,请检查定位开关", Toast.LENGTH_SHORT).show() } } } // 把q作为入参传入,避免全局变量脏数据问题 private fun callAPI(q: String){ apiServices.getUserDetails(key, q, days).enqueue( // 原有接口回调逻辑 ) } // 重写权限申请结果回调,用户同意权限后重新获取位置 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 101) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { fetchLocation() } else { Toast.makeText(requireContext(), "需要定位权限才能获取对应位置数据", Toast.LENGTH_SHORT).show() } } } }
额外优化说明
- 不要直接强转
context为Activity,优先用Fragment提供的requireContext()、requireActivity()方法,避免空指针崩溃 - 位置获取可能返回null,需要加异常分支处理,比如 fallback 到默认城市、提示用户打开定位等
- 不要滥用全局变量存异步结果,优先把需要的值作为函数参数传递,避免时序不同步导致的脏数据问题
内容的提问来源于stack exchange,提问作者Saveen Khan
相关产品推荐
相关产品推荐

