Android调用locationManager.requestLocationUpdates抛出LocationListener相关AbstractMethodError
报错根本原因
这个AbstractMethodError和你排查的依赖版本方向无关,和appcompat、material等第三方库的版本没有关联,核心是系统接口版本的运行时不兼容:
android.location.LocationListener在 Android 11(API 30)的系统版本中做了接口调整:原本全抽象的4个方法里,仅保留onLocationChanged(Location)为抽象方法,其余3个方法(onProviderDisabled、onProviderEnabled、onStatusChanged)都改成了带空默认实现的普通方法,让整个接口符合函数式接口的要求,可直接通过lambda表达式实现。- 你的项目设置的
minSdkVersion为25,意味着应用需要兼容API30以下的设备。在这些旧版本系统中,LocationListener的4个方法全部是无默认实现的抽象方法,你使用lambda表达式仅实现了onLocationChanged这一个方法,剩下3个方法没有任何可调用的实现逻辑,当系统尝试触发这些方法回调时,就会抛出找不到方法实现的AbstractMethodError。 - 编译阶段没有报错,是因为你设置的
compileSdkVersion为30,编译器按照API30的接口规则做语法校验,默认认为你只需要实现onLocationChanged方法,自然不会提示你补全其他方法的实现。你在项目里找不到可以重写方法的位置,也是因为你直接用lambda做了接口赋值,根本没有生成可以重写方法的匿名类结构。
适配兼容的解决方法
- 如果需要继续兼容
minSdkVersion 25的低版本设备,不能直接用lambda表达式赋值给LocationListener,需要改为实现完整的匿名类结构,手动补全所有方法的空实现:
LocationListener locationListener = new LocationListener() { @Override public void onLocationChanged(@NonNull Location location) { Toast.makeText(MainActivity.this, location.getLatitude() + " " + location.getLongitude(), Toast.LENGTH_LONG).show(); } @Override public void onProviderDisabled(@NonNull String provider) {} @Override public void onProviderEnabled(@NonNull String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {} };
- 如果后续项目不需要兼容API30以下的设备,可以将
minSdkVersion调整为30,这种场景下当前的lambda写法可以直接正常运行,因为系统运行时的接口本身就带了其他三个方法的空默认实现,不会出现方法缺失的问题。
内容的提问来源于stack exchange,提问作者Panagiss
相关产品推荐
相关产品推荐

