在Android P上运行根据SDK级别27构建的应用程序时,会意外地显示以下对话框(对话框标题是应用程序的名称):
已发现API兼容性问题(有关更多信息,请访问g.co/dev/appcompat)
URL指向this page about restrictions on non-SDK interfaces。我的应用程序本身不使用反射,但是使用了Gson。
Logcat中没有立即显而易见的日志消息,除了可能的消息,例如:
访问隐藏字段Landroid / widget / AbsListView;-> mIsChildViewEnabled:Z(浅灰色列表,反射)
答案 0 :(得分:8)
结果证明,我的一个Gson模型暴露了一个返回File的吸气剂。 Gson使用反射来递归检查类的字段,这样做违反了不允许的SDK接口的反射。
通过阅读问题中链接的限制文件,我可以更仔细地查看日志消息,而且确实可以引起我的注意:
访问隐藏字段[...](暗灰色列表,反射)
我记不清确切的信息了,但是这里的意思是它在暗灰名单中。
我是通过定位SDK级别28并启用新的StrictMode功能detectNonSdkApiUsage()
来发现这一点的,我的应用程序会因堆栈跟踪而崩溃:
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectNonSdkApiUsage()
.penaltyLog()
.build());
}
堆栈跟踪没有立即深入,但它为我指明了正确的方向。
答案 1 :(得分:0)
在应用程序类中的方法onCreate()初始化此方法可以关闭此对话框。
private void closeAndroidPDialog(){
try {
Class aClass = Class.forName("android.content.pm.PackageParser$Package");
Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
try {
Class cls = Class.forName("android.app.ActivityThread");
Method declaredMethod = cls.getDeclaredMethod("currentActivityThread");
declaredMethod.setAccessible(true);
Object activityThread = declaredMethod.invoke(null);
Field mHiddenApiWarningShown = cls.getDeclaredField("mHiddenApiWarningShown");
mHiddenApiWarningShown.setAccessible(true);
mHiddenApiWarningShown.setBoolean(activityThread, true);
} catch (Exception e) {
e.printStackTrace();
}
}
但这很危险 这样只是让您看不到对话框。