断网时FusedLocation调用geocoder.getFromLocation崩溃如何解决
问题根因
Geocoder.getFromLocation() 断网崩溃、try/catch不生效是Android平台的经典坑:
- 多数开发者写catch时只覆盖了
IOException,但断网场景下远程定位服务binder死亡抛出的InvocationTargetException会被包装成RuntimeException,不在常规IO异常的捕获范围内。 - Android 13(API 33)以下的同步
getFromLocation重载存在框架缺陷,部分厂商ROM上这个方法抛出的异常不会走正常的调用栈返回,会直接投递到线程未捕获异常处理器,就算写了catch也拦不住。 - 主动关闭网络的场景下,Geocoder依赖的后端服务直接不可用,会触发上述的框架异常路径。
可落地方案
按以下顺序调整代码,可完全覆盖断网无崩溃、异常可正常捕获的需求:
- 调用前增加前置校验,无网络、Geocoder服务不可用时直接跳过逆地理编码逻辑,不要硬调接口:
// 先判断Geocoder服务是否在当前设备可用 if (!Geocoder.isPresent()) { // 走无地址结果的业务逻辑,不再执行后续getFromLocation调用 return; } // 提前判断网络状态,无网络直接返回 ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (activeNetwork == null || !activeNetwork.isConnected()) { return; } - 补全异常捕获范围,低版本Android上不要只catch
IOException,直接捕获所有Exception兜底,覆盖你遇到的包装InvocationTargetException的RuntimeException:List<Address> addresses = null; try { // 注意:同步方法必须放在子线程调用,主线程调用除了ANR风险,部分ROM会直接抛异常 addresses = geocoder.getFromLocation(latitude, longitude, 1); } catch (IOException e) { // 处理常规IO、服务不可达异常 Log.e("Geocoder", "Get address IO error", e); } catch (RuntimeException e) { // 专门捕获断网触发的InvocationTargetException包装异常 Log.e("Geocoder", "Get address runtime error", e); } - Android 13及以上版本直接弃用同步
getFromLocation方法,改用官方提供的异步GeocodeListener回调版本,这个版本从框架层修复了异常逃逸的bug,断网场景只会走错误回调,不会触发崩溃:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { geocoder.getFromLocation(latitude, longitude, 1, new Geocoder.GeocodeListener() { @Override public void onGeocode(@NonNull List<Address> addrs) { // 正常处理地址结果 } @Override public void onError(@Nullable String errorMessage) { // 断网、服务异常都会走这个回调,不会崩溃 Log.e("Geocoder", "Geocode error: " + errorMessage); } }); } else { // 低版本走前面写的全量catch的子线程同步逻辑 }
原有try/catch失效的原因
你看到的
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException,本质是Geocoder的系统远程服务在断网时异常死亡,异常通过Binder反射链路返回时,旧版本框架没有把异常正常派发到你的业务代码调用栈,而是直接抛给了应用的未捕获异常处理器,仅catchIOException完全覆盖不到这类异常,才会出现写了捕获逻辑依然崩溃的现象。
内容的提问来源于stack exchange,提问作者Prasanna Kumar
相关产品推荐
相关产品推荐

