编写向后兼容的 Android 代码 [英] Writing backwards compatible Android code

查看:31
本文介绍了编写向后兼容的 Android 代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,该应用程序使用的一些函数和类仅在最新的 API 级别 - 16 中可用,但我希望它在 API 级别为 15 的设备上运行时没有错误.

I'm writing an app that uses some functions and classes only available in the latest API level - 16, but I want it to run with no errors on devices with API level 15.

让我们举几个例子.一个新类:Android.widget.Advanceable,以及一个新的/重命名的方法:View.setBackground():

Let's use a couple of examples. A new class: Android.widget.Advanceable, and a new/renamed method: 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.
}

如果我将 minSdk 设置为 15,但将构建目标设置为 16(即在项目属性->Android 中),它实际上会编译而不会出错.至少在某些时候.Eclipse 对错误有点随机,有时会说setBackground() 仅在 API 级别 >= 16"或类似级别可用,但如果我只是清理项目,这些错误就会神奇地消失.

And if I set a minSdk of 15 but a build target of 16 (i.e. in Project Properties->Android), it will actually compile with no errors. At least some of the time. Eclipse is a bit stochastic about the errors and will sometimes say "setBackground() is only available in API level >= 16" or similar, but if I just clean the project those errors magically go away.

所以我的问题是,我可以这样做吗?如果我在 API 级别 15 的设备上运行它,代码不会崩溃吗?只有当它真正到达 16 代码时它才会崩溃吗?为什么 Eclipse 不阻止我构建它?

So my question is, am I allowed to do this? Won't the code crash if I run it on an API level 15 device? Will it only crash if it actually gets to the 16 code? Why doesn't Eclipse stop me from building it?

感谢您的回答,我想问题应该是:为什么 lint 不会警告我使用新的 API?

Thanks for the answers, I guess the question should really be: Why won't lint warn me about using new APIs?

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

I have this in my manifest, and am using API level 16 functions but it still doesn't warn me:

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

此外,我仍然不确定整个类何时对于 API 级别都是新的,例如 Advanceable.特别是如果我将它们用作成员变量.

Also I'm still not sure about when entire classes are new to an API level, such as Advanceable. Specifically if I use them as member variables.

结果证明答案是Eclipse 有很多问题",但 Nico 的回答也很有帮助.

The answer turned out to be "Eclipse is buggy as hell", but Nico's answer was also very helpful.

推荐答案

内联 Api 错误是 ADT 的新内容,Eclipse 运行 Lint(我猜可能还有其他东西)来分析您的代码并将这些错误/警告内联.当您有关于优化或最佳实践的警告或提示时,这同样适用于 xml 布局.您可以使用注解来抑制类或特定方法中的这些错误.

Inline Api errors are new to ADT, Eclipse run Lint (and I guess something else maybe) to analyze your code and put those errors / warnings inline. The same apply to xml layout when you have warnings or hints about optimizations or best practices. You can use Annotations to suppress those errors in the class or in a particular method.

@TargetApi(16)
@SuppressLint("NewApi")

@TargetApi(16)
@SuppressLint("NewApi")

您放在这里的示例代码有问题,除了 API 级别检查之外,您在代码中还有一个 Advanceable 实例,该实例在 API 中不起作用 <16,因此检查 API 级别仅在调用新方法时有用,但不能在 IF 块之外引用新的 API 类.

There is a problem in the sample code you put here, beside the API level check you have an instance of Advanceable in the code that will not work in API < 16, so checking API level is only useful when you call new methods but you cant reference new API classes outside the IF block.

我认为可以接受的一种方法是创建一个抽象类和两个实现,然后实例化正确的实现,您可以使用带有静态方法的工厂类.

One approach I found acceptable is to create an abstract class and two implementations, then to instantiate the correct implementation you can use a factory class with static methods.

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

For example to create a view that use some new API classes and methods internally you need:

1 - 创建抽象类:

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 实现

      3 - API 16 implementation

      @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);
                }
        
            }
        }
        

        这篇关于编写向后兼容的 Android 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆