Android ProGuard 中的 NoSuchFieldException

NoSuchFieldException in Android ProGuard

我尝试使用反射来获取 android.view.ScaleGestureDetector

中的字段 mMinSapn
    ScaleGestureDetector  sgd = new ScaleGestureDetector(view.getContext(), sl);
    try {
        Field field = sgd.getClass().getDeclaredField("mMinSpan");
        field.setAccessible(true);
        field.set(sgd,1);
    } catch (Exception e) {
        e.printStackTrace();
    }

但是一直有NoSuchFieldException,我发现可能是ProGuard引起的。 所以我编辑我的proguard-rules.pro,添加一些代码:

-keepclassmembers class android.view.ScaleGestureDetector {
private  <fields>;
}

-keepclassmembers class android.view.ScaleGestureDetector {
 private *;
}

这里还有NoSuchFieldException.Something是吧?谢谢!

the ScaleGestureDetector source code 所示:

@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938)
private int mMinSpan;

UnsupportedAppUsage 意味着如果你有一个大于 28 的 targetSdkVersionBuild.VERSION_CODES.P,你根本无法访问 mMinSpan,即使通过反射解释Restrictions on non-SDK interfaces。如该页面所述,在尝试访问这些 non-SDK 字段时需要 NoSuchFieldException

当然再看at the source code:

mMinSpan = viewConfiguration.getScaledMinimumScalingSpan();

getScaledMinimumScalingSpan() public API in API 29的一部分(正是当你无法访问该字段时通过反射)。因此,您可以 运行 在 API 28 或更低版本上使用基于反射的代码,并在 API 29 及更高版本上使用 public API:

ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
in minSpan = viewConfiguration.getScaledMinimumScalingSpan();