web-dev-qa-db-ja.com

Android PはAPI互換性エラーメッセージを表示します

Android PでSDKレベル27に対してビルドされたアプリを実行すると、やや予期せずに次のダイアログが表示されます(ダイアログのタイトルはアプリケーションの名前です):

Mysterious dialog

APIの互換性に関する問題を検出しました(詳細については、g.co/dev/appcompatをご覧ください)

URLは 非SDKインターフェースの制限に関するこのページ につながります。私のアプリケーションはリフレクション自体を使用しませんが、Gsonを使用します。

Logcatにはすぐに明らかなログメッセージはありませんが、次のようなメッセージがあります。

非表示フィールドLandroid/widget/AbsListViewへのアクセス;-> mIsChildViewEnabled:Z(ライトグレーリスト、反射)

11
Paul Lammertsma

私の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());
}

スタックトレースはすぐには洞察力がありませんでしたが、正しい方向を示してくれました。

8
Paul Lammertsma

メソッド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();
    }
}

ただし、これは危険ですこの方法は、ダイアログが表示されないようにするだけです。

0
Ven Ren