Android PでSDKレベル27に対してビルドされたアプリを実行すると、やや予期せずに次のダイアログが表示されます(ダイアログのタイトルはアプリケーションの名前です):
APIの互換性に関する問題を検出しました(詳細については、g.co/dev/appcompatをご覧ください)
URLは 非SDKインターフェースの制限に関するこのページ につながります。私のアプリケーションはリフレクション自体を使用しませんが、Gsonを使用します。
Logcatにはすぐに明らかなログメッセージはありませんが、次のようなメッセージがあります。
非表示フィールドLandroid/widget/AbsListViewへのアクセス;-> mIsChildViewEnabled:Z(ライトグレーリスト、反射)
私のGsonモデルの1つが、Fileを返すゲッターを公開していることがわかりました。 Gsonはリフレクションを使用して再帰的にクラスのフィールドを検査しますが、そうすると、許可されていないSDKインターフェースのリフレクションに違反します。
質問にリンクされている制限文書を読むと、ログメッセージを詳しく見ることができました。
隠しフィールドへのアクセス[...](暗いグレーリスト、反射)
メッセージは正確には思い出せませんが、ここでのポイントは、それがdark greylistにあったということです。
SDKレベル28をターゲットにし、新しいStrictMode機能detectNonSdkApiUsage()
を有効にすることでこれを発見しました。これにより、アプリケーションがスタックトレースでクラッシュします。
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectNonSdkApiUsage()
.penaltyLog()
.build());
}
スタックトレースはすぐには洞察力がありませんでしたが、正しい方向を示してくれました。
メソッドonCreate()initのアプリケーションクラスで、このメソッドはこのダイアログを閉じることができます。
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();
}
}
ただし、これは危険ですこの方法は、ダイアログが表示されないようにするだけです。