dan
dan

Reputation: 249

Use preprocessor in Android project in Eclipse

I am trying to use preprocessor like #ifdef in my Android project in Eclipse. I did some research on this topic and found this link: Java Preprocessing Using Eclipse, which could potentially let me use preprocessor in Android project.

However, after I tried to build the project, it claimed something like package android.* does not exist. So, none of the android APIs could be found.

So, how should I add those libraries in the build path? Actually, android.jar file is under the Java Build Path already. Why does Eclipse still claims that?

Is there any other way to let me use the preprocessor in Android Project built in Eclipse?

Upvotes: 2

Views: 1992

Answers (1)

Alex Lockwood
Alex Lockwood

Reputation: 83311

You are programming in Java, not C/C++. Android development does not require the use of a preprocessor.


Edit:

My problem is we developed an Android app with USB functionality which is supported only by Android 3.1+. So, some of the USB libraries are imported, what I want is those imported libraries could be commented out using #ifdef, if we could, when we build the project for Android 2.2 or 2.3, etc. Is there any other workaround for this?

To make use of the classes/methods you mentioned, you'll have to build your application against the Android SDK version 3.1 or higher. However, you must also ensure that devices running version 3.0 or lower don't make use of these classes/methods during runtime, since doing so will result in a ClassNotFound exception.

The key take-away here is that you need to perform these checks at run-time. Since your application is compiled only once for all devices, a preprocessor could do nothing to prevent such an event from occurring. Instead, you need to explicitly protect against this in your code. This is usually done with a basic if-else statement. For example,

if (Build.VERSION_CODES.HONEYCOMB_MR1 >= Build.VERSION.SDK_INT) {
    // then you are on a device running android 3.1+ and it is
    // safe to make use of the new classes/methods
} else {
    // otherwise, you are running on a device running android 3.0
    // or lower. you should not make use of the new classes/methods.
}

Edit #2:

In response to bill's comment, which read:

Thank you, Alex. I built my project agaist 3.1, deployed it on 2.2 and run it. One last thing I am not quite sure I understand is I could debug the part of the code referred by the Android 3.1 on the Android 2.2 OS. Here is my explanation: after being built against 3.1, Java code is converted to machine code and HONEYCOMB_MR1 is just an integer although HONEYCOMB_MR1 is not present in 2.2, when I debugged it, the debugger goes to the line of HONEYCOMB_MR1, fetches that integer and compares with SDK_INT. In this way, the code could still be debugged although HONEYCOMB_MR1 is only in 3.1 SDK. Is that correct? Thanks.

I think you are understanding correctly. The more exact reasoning is that HONEYCOMB_MR1 is marked static final. Since the variable is an immutable constant (i.e. its value will never change), the integer is hard-coded into the bytecode when you compile the .apk. In So when your 2.2 device reaches the if statement, it checks to see if 12 > 8, thus avoiding a (failed) runtime search for HONEYCOMB_MR1.

This sort of thing actually happens quite frequently when you develop your Android application. For instance, this behavior also explains why you can use MATCH_PARENT (introduced in 2.2) on devices that should "technically" only support FILL_PARENT. Both constants have value -1; thus, when you run an app that uses MATCH_PARENT on a pre-Froyo device, all works as expected.

Upvotes: 3

Related Questions