Android P显示API兼容性错误消息

时间:2018-07-06 12:36:20

标签: android-9.0-pie

在Android P上运行根据SDK级别27构建的应用程序时,会意外地显示以下对话框(对话框标题是应用程序的名称):

Mysterious dialog

  

已发现API兼容性问题(有关更多信息,请访问g.co/dev/appcompat)

URL指向this page about restrictions on non-SDK interfaces。我的应用程序本身不使用反射,但是使用了Gson。

Logcat中没有立即显而易见的日志消息,除了可能的消息,例如:

  

访问隐藏字段Landroid / widget / AbsListView;-> mIsChildViewEnabled:Z(浅灰色列表,反射)

2 个答案:

答案 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();
    }
}

但这很危险 这样只是让您看不到对话框。