Можно загружать только определенные строки кода в соответствии с версией ОС Android?

Существует ли простая строка кода, которая позволяла бы загружать код только в том случае, если версия ОС соответствует требованиям?

Допустим, у меня целевая ОС как 2.2, но min sdk равен 3 для Android 1.5, поэтому даже если у меня есть некоторый код в моем проекте, который не совместим с 1.5, он все равно скомпилируется, поскольку целевая ОС - 2.2. В любом случае, я хочу объявить функцию, для которой требуется код, которого нет в 1.5 SDK, и он вызовет сбой, если он будет загружен на телефон 1.5. Есть ли такая простая вещь, которую я могу сделать? Так что мне не нужно делать все приложение недоступным для 1,5 пользователей?

 if (Android OS == >2.1){
            //Insert code here that requires 2.1 and up}
        else{
            //insert code that would appear is OS is <2.1}
7
задан Jeff 23 August 2010 в 23:38
поделиться

4 ответа

Да, вы можете это сделать. На самом деле существует более одного способа. (Примечание: единственная специфическая для Android часть этого ответа - это способ узнать версию платформы.)

Предположим, что класс X имеет метод void y() в версии 2.0 и далее, но не ранее.

Один из способов вызвать этот метод без внесения каких-либо зависимостей во время компиляции - использовать отражение для нахождения метода и вызвать invoke для него. Например:

X x = ...
if (BUILD.VERSION.RELEASE.compareTo("2.0") >= 0) {
    // (exception handling omitted ...)
    Method m = c.getClass().getDeclaredMethod("y");
    m.invoke(x);
}

Другой способ - создать API адаптера совместимости версий для вашего приложения следующим образом:

/** Version compatibility adapter API */
interface Compat {
    void doY();
}

/** Adapter class for version 1 */
class CompatV1 {
    public void y(X x) {
       // do nothing
    }
}

/** Adapter class for version 2 */
class CompatV2 {
    public void y(X x) {
       x.y();
    }
}

// 
// Code to instantiate the relevant adapter for the current platform.
//
Class<?> compatClass;
// (Exception handling omitted)
if (BUILD.VERSION.RELEASE.compareTo("2.0") < 0) {
    compatClass = Class.forName("...CompatV1");
} else {
    compatClass = Class.forName("...CompatV2");
}
// (Exception handling omitted)
Compat compat = (Compat) compatClass.newInstance();

// The adapter object can be passed around as a parameter, wrapped
// as a singleton or injected using dependency injection.

// Invoke X.y() as follows:

X x = ...
compat.y(x);

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

Этот подход требует немного больше размышлений, чтобы понять, как спроектировать API совместимости так, чтобы он чисто изолировал зависимости от версии от остального кода. Возможно, вам также придется пересмотреть API адаптера и создать новые классы адаптера для каждого нового (несовместимого) основного релиза.

Наконец, если изменения API платформы, к которым вам нужно адаптироваться, влекут за собой использование классов или методов в старой версии, которые удалены в новой версии, то вам придется компилировать различные классы адаптеров (например, классы CompatV*), используя различные Android SDK. Это значительно усложнит процесс сборки.


Другие "варианты" решения этой проблемы читайте в следующих статьях на Android Blog:

11
ответ дан 6 December 2019 в 19:30
поделиться

Вот еще один пример без отражения. http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html

2
ответ дан 6 December 2019 в 19:30
поделиться

Вы можете проверить с помощью Build.VERSION.RELEASE , он дает вам текущую версию вашей системы Android (1.5,1.6,2.1,2.2)

Подробнее о Build. ВЕРСИЯ

0
ответ дан 6 December 2019 в 19:30
поделиться
0
ответ дан 6 December 2019 в 19:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: