In-line annotations give syntax errors - android

I'm loving the new Lint API checks of ADT rev 17, but the new API Correctness Check has got me stumped. I have the following line of code:
listView.setOverScrollMode(OVER_SCROLL_NEVER);
Lint is reporting on this line:
Call requires API level 9 (current min is 4)
According to the documentation, I should just be able to add an annotation above the line, like so:
#TargetApi(9)
listView.setOverScrollMode(OVER_SCROLL_NEVER);
This, however, gives a syntax error in Java 1.6:
Syntax error on token(s), misplaced construct(s)

That's not allowed in Java (until/if JSR 308 gets added); you can only annotate classes, methods, fields, parameters and variable declarations. It's the latter that is shown in the docs. However, for bytecode based checks like the api check you may need to place it on a method or class (or anonymous/inner class). The Add Annotation quickfix for these warnings in lint should do the right thing.

Related

error: cannot find symbol method getColor(Context,int) after adding Sugar ORM to project

I would like to use SugarOrm in my app.
If I add the followings:
compile 'com.github.satyan:sugar:1.4'
to the gradle file
and
android:name="com.orm.SugarApp"
to my mainfest's application name
I get the following error on build:
Error:(75, 55) error: cannot find symbol method getColor(Context,int)
at this line:
holder.bg.setBackgroundColor(ContextCompat.getColor(ctx, R.color.primary_move));
If I checkout to a previous version without these 2 lines, my application builds and runds without error.
Any suggestions?
From the Android Documentation:
Helper for accessing features in Context introduced after API level 4
in a backwards compatible fashion.
Do you really need that backward compatibility? Try accesing getColor from the context. You can also still useContext.getColor() while you resolve the main issue however
I have updated to compile 'com.github.satyan:sugar:1.6' and error is gone.

'uiprintf' error in android PAC ROM compilation

I am getting this error while compiling PAC ROM.. I found printf error was discussed before and adviced to include . but this doesn't seems to work for uiPrintf.
This the exact line:
device/cyanogen/msm8916-common/recovery/recovery_updated.c:171.9: error: implicit declaration of function 'uiprintf'
Pls help..
Implicit declaration means using a function without declaring it before. Generally it used to give a warning for other cm based rom but pac makes this strict.
For your info,
uiprintf function's definition is in path "bootable/recovery/updater/install.h", and the datatypes used in the function are in updater.h. You may manually add the definitions but it will give an error after long time(almost at end) about redeclaration of uiprintf function.
To get along with this error just comment out that line in recovery-updater.c. It will not hurt anything (It's just for recovery ui printing).

Android TimePicker methods being stubs

(I am unsure if everyone else faces this problem, but I do)
I am accessing setHour(int) and getHour() (and the minute's getter and setter) of android.widget.TimePicker - IntelliJ doesn't complain of their inexistence, but when i run the program from my phone (or emulator) it crashes and i see an error log of java.lang.NoSuchMethodError android.widget.TimePicker.getHour. (Other minute/hour getter/setter include).
I tried accessing the definition for the TimePicker class (Ctrl+B) and I realised every method contained a line: throw RuntimeException("Stub");
So what's this; How can I move on?
IntelliJ doesn't complain of their inexistence
That is because you are compiling against API Level 23.
but when i run the program from my phone (or emulator) it crashes and i see an error log of java.lang.NoSuchMethodError android.widget.TimePicker.getHour
That is because getHour() was added in API Level 23, and your device or emulator is running Android 5.2 or below.
I don't use IntelliJ, but it should be complaining about your build. In Eclipse and Android Studio, you would get an error from Lint indicating that you are calling a method (getHour()) that exists in your compileSdkVersion (23) but does not exist in your minSdkVersion (whatever you have that set to, as the oldest API level that you are willing to support).
I tried accessing the definition for the TimePicker class (Ctrl+B) and I realised every method contained a line: throw RuntimeException("Stub")
That is because it is decompiling the android.jar that is in your compile-time classpath, which consists purely of stub implementations to satisfy the javac compiler. At runtime, your process' VM will have a version of that JAR that has actual implementations.
How can I move on?
Probably stop calling getHour(), unless you can get away with doing so only on Android 6.0+ devices.

what is the use of #SuppressLint("InlinedApi")

I encountered #SuppressLint("InlinedApi") in some code i was going through and could not find out any description of it online. I understand #SuppressLint("NewApi") is used to hide warnings when we write code that is higher than the minsdk mentioned in the manifest. But i am not able to figure out when "InlinedApi" should be used. Any ideas?
By executing lint --list (the lint tool is located in your sdk/tools directory) you can see a list of the valid issue id's. You can find the explanation of InlinedApi there :
"InlinedApi": Finds inlined fields that may or may not work on older
platforms
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.
I found this..
#SuppressLint("InlinedApi")
Indicates that Lint should ignore the specified warnings for the annotated element.
Exp:
SuppressLint
implements from Annotation Class.
android.annotation.SuppressLint like this..
Built-In Annotations
Java defines a set of annotations that are built into the language
Annotations applied to java code:
#Override - Checks that the method is an override. Causes a compile error if the method is not found in one of the parent classes or implemented interfaces.
#Deprecated - Marks the method as obsolete. Causes a compile warning if the method is used.
#SuppressWarnings - Instructs the compiler to suppress the compile time warnings specified in the annotation parameters
http://developer.android.com/reference/java/lang/annotation/Annotation.html
http://developer.android.com/reference/android/annotation/SuppressLint.html

Couldn't parse API file "frameworks/base/api/current.txt"

I tried adding some files in Android framework. Everything goes well, except in the end of compilation i am getting below error.
I tried make update-api too, but no luck, every time in compilation it is giving below errors. If anybody know how to overcome this, please let me know.
Docs droiddoc: out/target/common/docs/doc-comment-check
Checking API: checkapi-last
Checking API: checkapi-current
host layoutlib_create: out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar
Couldn't parse API file "frameworks/base/api/current.txt"
...as text: com.google.doclava.apicheck.ApiParseException: missing class or interface. got: private line 6342
...as XML: com.google.doclava.apicheck.ApiParseException: Error parsing API
Couldn't parse API file "out/target/common/obj/PACKAGING/public_api.txt"
...as text: com.google.doclava.apicheck.ApiParseException: missing class or interface. got: private line 6342
...as XML: com.google.doclava.apicheck.ApiParseException: Error parsing API
Exception in thread "main" java.lang.NullPointerException
at com.google.doclava.apicheck.ApiCheck.checkApi(ApiCheck.java:118)
at com.google.doclava.apicheck.ApiCheck.main(ApiCheck.java:67)
******************************
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
1) You can add "#hide" javadoc comments to the methods, etc. listed in the
errors above.
2) You can update current.txt by executing the following command:
make update-api
To submit the revised current.txt to the main Android repository,
you will need approval.
******************************
Couldn't parse API file "out/target/common/obj/PACKAGING/public_api.txt"
...as text: com.google.doclava.apicheck.ApiParseException: missing class or interface. got: private line 6342
...as XML: com.google.doclava.apicheck.ApiParseException: Error parsing API
Exception in thread "main" java.lang.NullPointerException
at com.google.doclava.apicheck.ApiInfo.isConsistent(ApiInfo.java:60)
at com.google.doclava.apicheck.ApiCheck.checkApi(ApiCheck.java:118)
at com.google.doclava.apicheck.ApiCheck.main(ApiCheck.java:67)
******************************
You have tried to change the API from what has been previously released in
an SDK. Please fix the errors listed above.
******************************
make: *** [out/target/common/obj/PACKAGING/checkapi-last-timestamp] Error 38
make: *** Waiting for unfinished jobs....
make: *** [out/target/common/obj/PACKAGING/checkapi-current-timestamp] Error 38
-rw-r--r-- 1 aankit admin 9763299 Jan 31 14:21 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
Output: out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar
Input : out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar
Input : out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
Found 7983 classes in input JARs.
Found 2260 classes to keep, 2143 class dependencies.
# deps classes: 2143
# keep classes: 2260
# renamed : 19
Created JAR file out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar
The reason for this issue was ,
Cause :- I was adding private classes in Android Frameworks and these classes documentation/declarations must be added to “frameworks/base/api/current.txt”
Solution :- as per error logs, There are two solutions.
1) add #hide annotation in each method's Signature in each newly added file and its members.
2) use commands $ make update-api then $ make -j4 or either use $make update-api && make -j4 , and code should be compilable now.
Have you tried to compile you code before updating api? It seems that the code you've added cannot be compiled.
The problem is that new api cannot be parsed.
If you check external/doclava/src/com/google/doclava/apicheck/ApiFile.java you'll find the the throw statement that can help you:
throw new ApiParseException("missing class or interface. got: " + token, tokenizer.getLine());
It seems that you try to add to api private class or interface that is not allowed. To check this try to look into out/target/common/obj/PACKAGING/public_api.txt file line number 6342. There you should find the name of the class or interface that causes the error.

Categories

Resources