【问题标题】:Android backward compatibility but still utilise latest API featuresAndroid 向后兼容,但仍使用最新的 API 功能
【发布时间】:2012-09-07 01:16:28
【问题描述】:

我在 Android Market 中注意到,许多流行的应用程序都向后兼容更早版本的 Android。 例如

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 吗?

编辑:另外,兼容性库扮演什么角色?这是钥匙吗?

谢谢。

【问题讨论】:

标签: android backwards-compatibility


【解决方案1】:

我们(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();
  }
}

一个用于

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

我建议支持 2.1 及更高版本,这样您就可以利用对 Dalvik 的改进并使用我列出的第一个示例。

【讨论】:

  • 感谢您的回答,我们最初计划支持 2.1/2.2,所以一切都很好:)
【解决方案2】:

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

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

是的,还有标准的Android Support (Compatibility) Library。通常,兼容库的目的是允许您的应用程序使用一些最新的操作系统功能,同时为旧平台提供一些类似的实现。你绝对应该调查一下。

还有一些很棒的第 3 方兼容性库。以下是我在项目中使用过的一些,绝对推荐:

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

【讨论】:

  • 也是一个很好的答案,可惜我只能选择一个。
  • HA tx,没问题...好的示例代码总是胜过自以为是 :)
【解决方案3】:

您可以做一些事情来支持旧版本的 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) 中引入了 Fragments。但是您可以在返回到 Donut (Api 4) 的设备上使用支持库中包含的 Fragments 版本!

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2012-03-22
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多