Building multi-SDK Android apps in Eclipse without losing compile-time checks
Asked Answered
B

2

7

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 boils 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.

Barfuss answered 4/10, 2011 at 0:50 Comment(0)
B
4

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

Barfuss answered 28/6, 2012 at 20:10 Comment(1)
Unfortunately the lint tools is quite unreliable, and often won't run or refresh properly.Aubrey
E
1

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.

Egalitarian answered 4/10, 2011 at 2:0 Comment(2)
Yeah, this is a good point. I should have mentioned this in my question. The downsides are that I lose any compile-time checking of the new code (since its all run-time resolved), and it can get really ugly quick if the new methods are complicated. But for my current code, the work-arounds I need are just a couple constants and two simple method calls, so it might be worthwhile.Barfuss
Agreed. Reflection is definitely a pain :)Egalitarian

© 2022 - 2024 — McMap. All rights reserved.