Building multi-SDK Android apps in Eclipse without losing compile-time checks
I am developing an Android app in Eclipse. I would like to target a wide variety of devices and SDK versions (for example, I can optionally support multi-touch). I understand the recommended approach of isolating all the new functionality to a separate class and leveraging lazy loading to only load that class at run-time if the host device actually supports the feature.
The downside of this approach is that I have to compile all of my code with the SDK of the newest feature I want to use. Which means if some new feature leaks into my "version neutral" code, the compiler can no longer catch it.
I would like the ability, within Eclipse, to compile my project against an older Android SDK to make sure my "version neutral" code is fine. I'd like to avoid moving my build system out of Eclipse, if possible. I'm okay with this old-SDK build being a bit awkward to run.
I think this b开发者_开发问答oils down to doing some conditional compliation (or conditional "linking") inside Eclipse? For example, in my project when building against SDK-1.6 I'd like to leave the "MultiTouchHandler.java" source out of the build. I'm not sure if its possible to express "build types" like this in Eclipse, though.
The hacky solution seem to be just manually changing the project's SDK version, rebuilding, and looking through the errors, and ignore 'expected' errors. The overkill solution seems to be writing my own ant/maven/make build scripts.
Related Questions
This question: Versioning and common code-bases with Eclipse covers similar ground, but would involve moving all of the version-specific classes into separate "libraries". (And I would still have the problem of multiple build types in Eclipse, I think.)
This question: Build multiple project configurations with eclipse implies that I should move to an external build system (like ant or maven), but that's a lot more work than just trying a build with an old SDK from time to time.
The February 2012 (v17) updates to the Lint Tool in the ADT should help address this without requiring multiple builds. When an app targets an old minimum SDK, but is compiled against the newest SDK (as is the recommended practice), the lint tool will notice if calls to the newer SDK are invoked. If you're confident the call is okay (Because you've hidden it behind a run-time SDK_INT check, or whatever), you can Quick-Fix an annotation to prevent the warning.
For example, in my code I have a call to View.setSystemUiVisibility, which was introduced in API 11, but I'm targetting API 8. Running Lint shows:
Call requires API level 11 (current min is 8): android.view.View#setSystemuiVisibility
The QuickFix suggests two kinds of fixes, either adding an annotation that suppresses the warning or adding an annotation that declares a chunk of code as working at API 11.
More details here: http://tools.android.com/recent/lintapicheck
A somewhat less clean/less performant method would be to use reflection to access the newer apis that you need, rather than trying to reference them directly with lazy loading. This should allow you to compile against a lower sdk level.
精彩评论