Обратная совместимость с Android, но по-прежнему используют новейшие функции API

Я заметил в Android Market, что многие популярные приложения имеют обратную совместимость с гораздо более ранними версиями Android. Например.

Evernote - 1.6
Faceobook Messenger - 2.2

Эти приложения выглядят и отлично работают, но как они могут это сделать и поддерживать гораздо более старые уровни API? Являются ли они только функциями API, которые существуют в самой низкой версии ОС, вряд ли? Я предполагаю, что они должны использовать некоторые функции более поздних уровней API для обеспечения отличного интерфейса и списка функций.

Я вижу два возможных решения:

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?

EDIT: Также, какую роль играют библиотеки совместимости? Это ключ?

Спасибо.

Ответ 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

Существует несколько различных стратегий для смещения обратной поддержки с последними функциями. В документации по Android есть много ссылок, но, возможно, начинайте здесь: Обратная совместимость для приложений Android.

Но в целом я бы настоятельно рекомендовал вам не публиковать несколько версий, если это возможно. Используйте манифест приложения, чтобы настроить соответствующий диапазон версий ОС и кода.

И да, есть также стандартная Библиотека поддержки Android (совместимость). В общем, цель библиотек-совместителей - позволить вашему приложению использовать некоторые из последних функций ОС, обеспечивая при этом сопоставимую реализацию для более старых платформ. Вы должны обязательно изучить это.

Также есть несколько замечательных сторонних библиотек совместимости. Вот несколько примеров, которые я использовал в своих проектах и ​​определенно рекомендую:

Обратите внимание, что NineOldAndroids фактически включен в ActionBarSherlock.

Ответ 3

Есть несколько вещей, которые вы можете сделать, чтобы поддерживать более старые версии платформы Android, все еще пользуясь преимуществами новых версий. Руководство по обучению Android Поддержка разных версий платформы описывает несколько и содержит пример кода, показывающий, как реализовать их.

Без особого порядка:

  • Вы можете установить отдельную "minSdkVersion" и "targetSdkVersion". minSdkVersion - это самая ранняя версия Android, которую вы хотите поддержать. targetSdkVersion - это последняя версия, на которую вы протестировали, и самый последний набор функций/поведений, которые вы собираетесь включить в свое приложение.

  • Вы можете проверить системные версии во время выполнения и реализовать только функцию, если на устройстве установлена ​​требуемая версия Android Platform. Это выглядит так:

    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)!