Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When code requires an certain API level, why must the check for Build.Version be the same required rather than at or above the required level?

I was watching an android developers video (https://www.youtube.com/watch?v=3UbJhmkeSig) on property animations when I ran into a problem that's easy to fix but difficult for me to understand and was hoping someone could shine some light on it for me..

I have a project that is targeting API level 8 in the manifest so when I used the code below I got an error stating that the code used requires a higher API level than the currently targeted API level. As a work around I checked for the Build version at runtime (http://developer.android.com/training/basics/supporting-devices/platforms.html) and only ran the code segment if the API level sufficed.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(resp1, View.ROTATION, 270);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            rotateAnimation.setRepeatCount(0);
        }
    }

My confusion came about when I added the first, outer-most if statement. The line of code

 ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(resp1, View.ROTATION, 270);

requires API level 14 hence my reason for checking the Build.Version.ICS. However, the method the "setRepeatCout()" method from the line of code

            rotateAnimation.setRepeatCount(0);

requires API 11 and although placed inside the first, outer-most if statement with brackets to insure a block and not a line, my IDE (IntelliJ IDEA) still presented me with errors stating that the line of code requires API 11 and my project targets API 8. My two solutions was to place the code into two nested if statements one checking for API 14 and the other API 11 or to use the

@TargetApi(Build.VERSION_CODES.HONEYCOMB)

annotation at the beginning of the method. However, I don't fully understand the annotation in regards to how it effects older devices nor do I understand why I needed two if statements to check for the Build version.

-Does @TargetAPI simply get rid the lint check or does it somehow effect the entire method and whether or not it compiles/runs?

-Why was I required to use two if statements? Why didn't the first if statement suffice for both lines of code?

-Is there a reason for needing to check the build using both if statements or is this perhaps a bug? I tried searching for known bugs at https://youtrack.jetbrains.com/issues/IDEA and search results on google.

Many thanks

like image 942
cjayem13 Avatar asked Nov 01 '22 16:11

cjayem13


1 Answers

Does @TargetAPI simply get rid the lint check or does it somehow effect the entire method and whether or not it compiles/runs?

It indicates to Lint that, for the scope of the annotation (method or class), Lint should treat the minSdkVersion as being the value supplied in the annotation (e.g., HONEYCOMB), rather than whatever you have it specified as in your manifest or build.gradle file.

You apply @TargetApi when you, as a developer, have validated that you are handling backwards compatibility properly for that specified API level. Then, some time in the future, if you add more code to the class or method that is higher than this API level, that Lint should yell at you again, so you realize that you need to add more backwards-compatibility checking.

In this case, the right solution was @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH), as your code is set up to handle backwards compatibility from your current minSdkVersion through API Level 14, but no higher (as you aren't using anything at issue that is higher).

Why was I required to use two if statements? Why didn't the first if statement suffice for both lines of code?

Possibly because of your choice of HONEYCOMB for the @TargetApi annotation. If we are on a device running API Level 14 or higher, we are on a device running API Level 11 or higher by definition. You do not need the inner if check.

Is there a reason for needing to check the build at both locations or is this perhaps a bug?

I do not know what you consider the "both locations" to be. Do you need the @TargetApi annotation and the outer if check? Yes. Do you need both if checks? No. And, if you set the @TargetApi to ICE_CREAM_SANDWICH, remove the inner if check, and get Lint complaints, that's probably a bug in the Android plugin.

like image 76
CommonsWare Avatar answered Nov 09 '22 06:11

CommonsWare