关于AbstractMethodError: abstract method "void android.telephony.TelephonyManager$

462 阅读1分钟

一、现象

混淆后,Android 10及以上系统会抛出这个异常:

java.lang.AbstractMethodError: abstract method "void android.telephony.TelephonyManager$CellInfoCallback.onCellInfo(java.util.List)"
	at android.telephony.TelephonyManager$3.lambda$onCellInfo$0(TelephonyManager.java:6520)
	at android.telephony.TelephonyManager$3$$ExternalSyntheticLambda1.run(Unknown Source:4)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.lang.Thread.run(Thread.java:930)

二、原因

因为Android 29才引入TelephonyManager$CellInfoCallback这个内部类。

  1. 当compileSdk 28及以下时开启混淆后会直接编译为:
    public final class a extends TelephonyManager.CellInfoCallback {
        public a(b b) {
        }
    }

会忽略重写的onCellInfo(List)方法,当运行在29及以上的系统上则会抛出异常。

  1. 当compileSdk 29及以上时开启混淆编译后才会正常重写onCellInfo(List)方法
    public final class a extends TelephonyManager.CellInfoCallback {
        public a(b b) {
        }

        @Override // android.telephony.TelephonyManager.CellInfoCallback
        public void onCellInfo(List<CellInfo> list) {
        }
    }

三、解决

  1. 最简单的方法就是直接 compileSdk 版本设置到29以上
  2. 如果不想升级compileSdk版本,也可添加混淆忽略文件:
-keepclassmembers class com.类名 {<methods>;}//如果是内部类用$分割

四、参考文章

  1. AbstractMethodError: abstract method "void android.telephony.TelephonyManager$CellInfoCallback.on...
  2. ProGuard 使用详解