编写向后兼容的Android代码

我正在编写一个应用程序,它只使用最新API级别的某些函数和类 – 16,但是我希望它在API级别为15的设备上运行时没有错误。

我们来举几个例子。 一个新的类: Android.widget.Advanceable和一个新的/重命名的方法: View.setBackground()

我可以做这样的事情:

 Advanceable myAdvanceable = ...; if (android.os.Build.VERSION.SDK_INT >= 16) { myView.setBackground(...); myAdvanceable.advance(); } else { myView.setBackgroundDrawable(...); // The old function name. // Don't bother advancing advanceables. } 

如果我设置15的minSdk,但build立目标是16(即在项目属性 – > Android),它将实际编译没有错误。 至less有一些时间。 Eclipse对这些错误有些随意,有时候会说“setBackground()只能在API级别> = 16”或类似的情况下才可用,但是如果我只是清理项目,这些错误就会消失。

所以我的问题是,我允许这样做吗? 如果我在API 15级设备上运行代码,会不会崩溃? 它只会崩溃,如果它实际上得到16代码? Eclipse为什么不阻止我构build它?

编辑1

感谢您的答案,我想这个问题应该是:为什么不皮棉警告我使用新的API?

我在清单中有这个,并且正在使用API​​级别16的函数,但它仍然不会警告我:

 <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="16"/> 

另外我还不确定整个类是什么时候是API级别的新类,比如Advanceable 。 特别是如果我使用它们作为成员variables。

编辑2

答案竟然是“Eclipse就像地狱一样”,但是Nico的回答也非常有帮助。

内联Api错误是ADT的新function,Eclipse运行Lint(我想别的也许可能)来分析你的代码,并把这些错误/警告内联。 当您有关于优化或最佳实践的警告或提示时,也适用于xml布局。 您可以使用批注来抑制类或特定方法中的这些错误。

@TargetApi(16)
@SuppressLint( “NewApi”)

您在这里放置的示例代码中存在一个问题,除了API级别检查,您在代码中有一个Advanceable实例,在API <16中不起作用,所以检查API级别仅在调用新方法时有用,在IF块之外引用新的API类。

我发现一种可以接受的方法是创build一个抽象类和两个实现,然后实例化正确的实现,您可以使用静态方法使用工厂类。

例如,要创build一个在内部使用一些新的API类和方法的视图,您需要:

1 – 创build抽象类:

 public abstract class CustomView { public abstract void doSomething(); } 
  • 与所有API兼容的通用实现
  • 在这里定义抽象方法来分割实现

2 – 遗留的实现

 public class CustomLegacyView extends CustomView { public void doSomething(){ //implement api < 16 } } 
  • 实现API <16的抽象方法

3 – API 16的实现

 @TargetApi(16) public class CustomL16View extends CustomView { Advanceable myAdvanceable; public void doSomething(){ //implement api >= 16 } } 
  • 使用注解@TargetApi(16)
  • 实现API> = 16的抽象方法
  • 你可以在这里引用16级的类(但不能在CustomView中)

4 – 工厂类

 public class ViewFactory { public static CustomView getCustomView(Context context) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { return new CustomL16View(context); }else{ return new CustomLegacyView(context); } } } 

使用更新的构build目标是一个常见的做法,并保证在适当的环境下调用更新的API。 Google甚至在ADT 17之后还添加了@TargetApi()注释,为有条件加载的代码指定本地覆盖。

请参阅Lint API检查以获取更多详细信息。

1.您有Target ApiMinimum SDK属性来定义您定位的设备types, 以及哪个设备将运行的最less的Api版本

2. Target Api应用程序运行Fullfunction的 Target Api ,而Minimum SDK将使应用程序运行一些妥协,因为可能有更低的API版本不具有更高版本的function