Android向后兼容性,但仍使用最新的API功能

时间:2012-09-04 22:47:47

标签: android backwards-compatibility

我在Android Market中注意到许多流行的应用程序都向后兼容早期版本的Android。 E.g。

Evernote - 1.6
Faceobook Messenger - 2.2

这些应用程序外观和工作都很棒,但他们如何做到这一点并支持更旧的API级别?他们只使用支持最低的操作系统版本中存在的API功能吗?我假设他们必须使用更高级API级别的某些功能来提供出色的UI和功能列表。

我可以看到两种可能的解决方案:

Use Min/Target API levels in build. Then through code you check the OS version and implement the features using a supported method and degrade gracefully. This seems like a lot of work.

Have multiple app versions targeting various OS versions. E.g. A release for 2.2 and another for 4.0. Is this possible?

问的原因是我正在计划一个应该支持2.2的新应用程序但我担心我可能需要仅在以后的版本中提供的API功能?我应该只针对2.2吗?

编辑:此外,兼容性库的作用是什么?这是关键吗?

感谢。

3 个答案:

答案 0 :(得分:15)

我们(Evernote)做额外的工作来支持1.6并尽可能多地使用新的API。支持1.6的主要问题是Dalvik对你的课程进行了贪婪的搜索。这使得无法使用像

这样的代码
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
    prefEditor.apply();
} else {
    prefEditor.commit();
}

因为它会抛出类验证错误。当dalvik看到您的方法并尝试在运行时访问它时会导致这种情况。

相反,您需要使用帮助程序类来实例化SDK的相应类。是的,这是更多的工作

public abstract class SharedPreferenceEditor {

  private static SharedPreferenceEditor sInstance;

  public static SharedPreferenceEditor getInstance() {
    if (sInstance == null) {

      /*
      * Check the version of the SDK we are running on. Choose an
      * implementation class designed for that version of the SDK.
      */
      @SuppressWarnings("deprecation")
      int sdkVersion = Build.VERSION.SDK_INT;
      if(Evernote.DEBUG)Log.d("SharedPreferenceEditor", "sdkVersion=" + sdkVersion);
      if (sdkVersion < Build.VERSION_CODES.GINGERBREAD) {
        sInstance = new CommitSharedPreferenceEditor();
      } else  {
        sInstance = new ApplySharedPreferenceEditor();
      }
    }
    return sInstance;
  }

  public abstract void save(SharedPreferences.Editor editor);
}

然后你有一个姜饼+ api水平

public class ApplySharedPreferenceEditor extends SharedPreferenceEditor {
  public void save(SharedPreferences.Editor editor) {
    editor.apply();
  }
}

和一个&lt;姜饼水平

public class CommitSharedPreferenceEditor extends SharedPreferenceEditor{
  public void save(SharedPreferences.Editor editor) {
    editor.commit();
  }
}

我建议支持2.1及以上,以便您可以利用Dalvik的改进并使用我列出的第一个示例。

答案 1 :(得分:6)

将向后支持与最新功能混合有几种不同的策略。 Android文档中有很多引用,但可以从这里开始: Backward compatibility for Android applications

但总的来说,我强烈建议您尽可能避免发布多个版本。使用应用程序的清单来相应地定位适当范围的操作系统版本和代码。

是的,还有标准的Android Support (Compatibility) Library。通常,compat库的目的是允许您的应用程序使用一些最新的OS功能,同时为旧平台提供一些类似的实现。你一定要看看这个。

还有一些很棒的第三方兼容性库。这是我在项目中使用的一些内容,但绝对值得推荐:

请注意,NineOldAndroids实际上包含在ActionBarSherlock中。

答案 2 :(得分:1)

您可以采取一些措施来支持较旧版本的Android平台,同时仍然可以利用新版本中的功能。 Android培训指南Supporting Different Platform Versions概述了一些内容,并提供了示例代码,说明如何实施它们。

没有特别的顺序:

  • 您可以设置单独的“minSdkVersion”和“targetSdkVersion”。 minSdkVersion是您想要支持的最早版本的Android。 targetSdkVersion是您测试过的最新版本,以及您打算在应用中包含的最新功能/行为。

  • 您可以在运行时检查系统版本,只有在设备上运行必需的Android平台版本时才能实现功能。这看起来像:

    private void setUpActionBar() {
        // Make sure we're running on Honeycomb or higher to use ActionBar APIs
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
          ActionBar actionBar = getActionBar();
          actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }
    
  • 支持库(通常也称为兼容性库)包含Android新版本的功能,这些功能的编写方式使您可以将它们包含在应用程序中,甚至可以在旧的版本的Android。例如,片段是在Honeycomb(Api 11)中引入的。但您可以在返回Donut(Api 4)的设备上使用支持库中包含的片段版本!