what is the use of @SuppressLint(“InlinedApi”)

后端 未结 3 1452
长发绾君心
长发绾君心 2021-02-05 11:14

I encountered @SuppressLint(\"InlinedApi\") in some code i was going through and could not find out any description of it online. I understand @SuppressLint(\

3条回答
  •  清酒与你
    2021-02-05 11:52

    Here's an example from a Google codelab:

    @SuppressLint("InlinedApi")
    private void hideSystemUi() {
        mPlayerView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    }
    

    If you comment out the @SuppressLint("InlinedApi"), you get this lint warning:

    Field requires API level 19 (current min is 16): android.view.View#SYSTEM_UI_FLAG_IMMERSIVE_STICKY

    So you're accessing a field that may not exist in the API of some of the devices that you've said you want to be able to run the device on. In that case, why is it just a lint warning instead of a fatal compile error?

    The fuller description for the warning is nice and informative. You can see it in Android Studio if you press the "More" key combo (e.g. Cmd+F1) when the lint message popup is open. You can also get it via lint on the command line, similar to what @stan0 said but in more detail:

    lint --show InlinedApi
    

    Here's the detailed explanation:

    InlinedApi
    ----------
    Summary: Using inlined constants on older versions

    Priority: 6 / 10
    Severity: Warning
    Category: Correctness

    This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that's fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and decide whether it's safe and can be suppressed or whether the code needs to be guarded. [emphasis added]

    If you really want to use this API and don't need to support older devices just set the minSdkVersion in your build.gradle or AndroidManifest.xml files. If your code is deliberately accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the @TargetApi annotation specifying the local minimum SDK to apply, such as @TargetApi(11), such that this check considers 11 rather than your manifest file's minimum SDK as the required API level.

    (source)

    Hopefully with that explanation, it's clear why this is not a fatal error (because the value of the constant gets copied into the class file instead of a reference), why it's still potentially dangerous, and when to suppress the warning. In the codelab example above, the author apparently decided that adding a flag that wouldn't be recognized on older devices was safe. Maybe he had information that unrecognized flags would be silently ignored, though I don't see that in the documentation.

提交回复
热议问题