Версия Android Min SDK против целевой версии SDK

429

Когда дело доходит до разработки приложений для Android, в чем разница между версией Min и Target SDK? Eclipse не позволит мне создать новый проект, если Min и Target не совпадают!

  • 1
    Из того, что я читаю, похоже, что версия Target SDK не влияет на то, как компилируется ваше приложение. Просто для того, чтобы сообщить устройству, на котором запущено приложение, ему не нужно включать какие-либо специальные функции совместимости для правильной работы приложения. Это правильно? Мне кажется, что вы не знаете, какая у вас целевая версия SDK, пока ПОСЛЕ того, как вы скомпилировали и провели много испытаний. Почему компилятор не может просто посмотреть на ваш код и выяснить, с какими платформами ваше приложение совместимо само по себе?
  • 5
    Комментатор выше неправильно понял, почему кто-то использует функцию targetSDK. Смотрите мой ответ ниже для более подробной информации.
Показать ещё 5 комментариев
Теги:

8 ответов

136
Лучший ответ

андроида: minSdkVersion

Целое число, обозначающее минимальный уровень API, необходимый для запуска приложения. Система Android не позволит пользователю установить приложение, если уровень API системы ниже, чем значение, указанное в этом атрибуте. Вы всегда должны объявлять этот атрибут.

android: targetSdkVersion

Целое число, обозначающее уровень API, на который нацелено приложение.

С этим набором атрибутов приложение говорит, что оно может работать в более старых версиях (вплоть до minSdkVersion), но было явно протестировано для работы с указанной здесь версией. Указание этой целевой версии позволяет платформе отключать параметры совместимости, которые не требуются для целевой версии (которые в противном случае могут быть включены для поддержания передовой совместимости) или включить новые функции, недоступные старым приложениям. Это не означает, что вы можете программировать разные функции для разных версий платформы - она ​​просто информирует платформу, которую вы протестировали против целевой версии, и платформа не должна выполнять какую-либо дополнительную работу для поддержания совместимости с целевой версией.

Для получения дополнительной информации обратитесь к этому URL-адресу:

http://developer.android.com/guide/topics/manifest/uses-sdk-element.html

  • 0
    По большому счету, вы собираетесь установить одно и то же. Скорее всего, будет необычная ситуация, когда они будут установлены на разные значения.
  • 66
    Что касается комментария JJB: я не согласен. Есть много веских причин, по которым у вас могут быть разные minSDK и targetSDK. Смотрите мой ответ для более подробной информации.
880

Комментарий, отправленный OP к вопросу (в основном из-за того, что targetSDK не влияет на компиляцию приложения) совершенно неверен! Извините, что вы тупой.

Вкратце, вот цель объявления другого targetSDK из minSDK: это означает, что вы используете функции с SDK более высокого уровня, чем ваш минимум, но у вас обеспечивается обратная совместимость. Другими словами, представьте, что вы хотите использовать функцию, которая была только недавно введена, но это не критично для вашего приложения. Затем вы установили targetSDK в версию, в которой была введена эта новая функция, а минимальная - на что-то ниже, чтобы все могли использовать ваше приложение.

Чтобы привести пример, скажем, вы пишете приложение, которое широко использует обнаружение жестов. Однако каждая команда, которая может быть распознана жестом, также может быть выполнена с помощью кнопки или из меню. В этом случае жесты являются "отличными", но не требуются. Поэтому вы должны установить целевой sdk в 7 ( "Eclair", когда была введена библиотека GestureDetection), а минимальная SDK - на уровень 3 ( "Cupcake" ), чтобы даже люди с действительно старыми телефонами могли использовать ваше приложение. Все, что вам нужно сделать, это убедиться, что ваше приложение проверило версию Android, на которой она работала, прежде чем пытаться использовать библиотеку жестов, чтобы не пытаться использовать ее, если она не существует. (По общему признанию, это датированный пример, так как вряд ли у кого по-прежнему есть телефон v1.5, но было время, когда поддержание совместимости с v1.5 было действительно важно.)

Чтобы привести еще один пример, вы можете использовать это, если хотите использовать функцию из Gingerbread или Honeycomb. Некоторые люди скоро получат обновления, но многие другие, в частности со старыми аппаратными средствами, могут оставаться застрявшими с Eclair, пока не приобретут новое устройство. Это позволит вам использовать некоторые из новых интересных функций, но не исключая часть вашего возможного рынка.

Существует действительно хорошая статья из блог разработчиков Android о том, как использовать эту функцию, и, в частности, как разработать" чек перед тем, как использовать его, существует функция, указанная выше.

В OP: я написал это в основном для всех, кто случайно наткнулся на этот вопрос в будущем, так как я понимаю, что ваш вопрос был задан давно.

  • 2
    Не могли бы вы дать точное объяснение того, как targetSDKversion влияет на компиляцию приложения? Потому что версия компиляции - это еще одна конфигурация, которую вам нужно настроить. заранее спасибо
  • 0
    hnviet: если вы говорите о настройке версии компилятора Java, то это совершенно другое. На самом деле, вам вообще не нужно с этим связываться. Он должен быть установлен на 1.6, а затем просто оставить его там. Если у вас возникли проблемы с ним, это связано с тем, как вы настроили Eclipse.
Показать ещё 18 комментариев
94

Когда вы устанавливаете targetSdkVersion = "xx", вы подтверждаете, что ваше приложение работает правильно (например, было тщательно и успешно протестировано) на уровне API xx.

Версия Android, работающая на уровне API выше xx, автоматически применит код совместимости для поддержки любых функций, на которые вы могли бы полагаться, которые были доступны на уровне xx до уровня API xx, но которые теперь устарели на этой версии более высокого уровня Android.

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

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

Как указано в других ответах, вы можете установить targetSdkVersion выше, чем minSdkVersion, если вы хотите использовать некоторые функции API, первоначально определенные на более высоких уровнях API, чем ваши minSdkVersion, и предприняли шаги для обеспечения того, чтобы ваш код мог обнаруживать и обрабатывать отсутствие эти функции на более низких уровнях, чем targetSdkVersion.

Чтобы разработчики специально тестировали минимальный уровень API, необходимый для использования функции, компилятор выдаст ошибку (а не просто предупреждение), если код содержит вызов любого метода, который был определен на более позднем уровне API чем minSdkVersion, даже если targetSdkVersion больше или равно уровню API, на котором этот метод был впервые доступен. Чтобы удалить эту ошибку, директива компилятора

@TargetApi(nn)

сообщает компилятору, что код в рамках этой директивы (который будет предшествовать методу или классу) был написан для тестирования уровня API по крайней мере nn до вызова любого метода, который зависит от наличия по меньшей мере этот уровень API. Например, следующий код определяет метод, который может быть вызван из кода в приложении, которое имеет minSdkVersion меньше 11 и targetSdkVersion 11 или выше:

@TargetApi(11)
    public void refreshActionBarIfApi11OrHigher() {
      //If the API is 11 or higher, set up the actionBar and display it
      if(Build.VERSION.SDK_INT >= 11) {
        //ActionBar only exists at API level 11 or higher
        ActionBar actionBar = getActionBar();

        //This should cause onPrepareOptionsMenu() to be called.
        // In versions of the API prior to 11, this only occurred when the user pressed 
        // the dedicated menu button, but at level 11 and above, the action bar is 
        // typically displayed continuously and so you will need to call this
        // each time the options on your menu change.
        invalidateOptionsMenu();

        //Show the bar
        actionBar.show();
    }
}

Возможно, вы также захотите объявить более высокую targetSdkVersion, если бы вы протестировали на этом более высоком уровне, и все сработало, даже если вы не использовали какие-либо функции с уровня API выше, чем ваш minSdkVersion. Это было бы просто для того, чтобы избежать накладных расходов на доступ к коду совместимости, предназначенному для адаптации с целевого уровня до минимального уровня, поскольку вы бы подтвердили (посредством тестирования), что такая адаптация не требуется.

Примером функции пользовательского интерфейса, которая зависит от объявленной targetSdkVersion, будет кнопка меню с тремя вертикальными точками, которая отображается в строке состояния приложений с целевой версией targetSdkVersion меньше 11, когда эти приложения работают под API 11 и выше, Если ваше приложение имеет targetSdkVersion 10 или ниже, предполагается, что ваш интерфейс приложения зависит от наличия выделенной кнопки меню, и поэтому появляется кнопка с тремя точками вместо ранее выделенного оборудования и/или экранных версий этой кнопки (например, как показано в Gingerbread), когда ОС имеет более высокий уровень API, для которого больше не требуется выделенная кнопка меню на устройстве. Однако, если вы настроили приложение targetSdkVersion на 11 или выше, предполагается, что вы воспользовались функциями, представленными на этом уровне, которые заменяют выделенную кнопку меню (например, панель действий) или что вы в противном случае обошли необходимость иметь кнопку системного меню; следовательно, исчезает меню "кнопка совместимости с тремя вертикальными точками". В этом случае, если пользователь не может найти кнопку меню, она не может нажимать на нее, а это, в свою очередь, означает, что ваша активность onCreateOptionsMenu (меню) переопределения никогда не будет вызвана, что, опять же, в свою очередь, означает, что значительная часть функциональности вашего приложения может быть лишена пользовательского интерфейса. Если, конечно, вы не внедрили панель действий или какие-то другие альтернативные средства для доступа пользователей к этим функциям.

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

Примером использования minSdkVersion для обеспечения наличия функции, не связанной с API, было бы установить minSdkVersion на 8, чтобы гарантировать, что ваше приложение будет работать только в версии интерпретатора Dalvik с поддержкой JIT (поскольку JIT был представлен интерпретатору Android на уровне API 8). Поскольку производительность для интерпретатора с поддержкой JIT может быть в пять раз больше, чем у тех, у кого отсутствует эта функция, если ваше приложение сильно использует процессор, тогда вам может потребоваться уровень API 8 или выше, чтобы обеспечить адекватную производительность.

  • 0
    Спасибо за инструкции по использованию директивы TargetApi.
  • 0
    @Carl Означает ли это, что я всегда могу установить targetSdkVersion на любую версию выше, чем у моего minSdkVersion (особенно для получения этих улучшений пользовательского интерфейса) без необходимости какого-либо тестирования ( как такового ), если я ограничиваю свою кодовую базу для использования только API, доступных в моем minSdkVersion ?
Показать ещё 3 комментария
49

Концепция может быть лучше доставлена ​​с примерами, всегда. У меня возникла проблема в понимании этой концепции, пока я не подкопался в исходном коде Android и не проведу эксперименты, даже после прочтения всех документов на сайтах разработчиков Android и связанных с ними потоках stackoverflow. Я собираюсь поделиться двумя примерами, которые помогли мне полностью понять эти концепции.

A DatePickerDialog будет выглядеть по-разному в зависимости от уровня, который вы помещаете в файл AndroidManifest.xml targetSDKversion (<uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>). Если вы установите значение 10 или ниже, ваш DatePickerDialog будет выглядеть как слева. С другой стороны, если вы установите значение 11 или выше, DatePickerDialog будет выглядеть правильно, с тем же кодом.

Изображение 3190Изображение 3191

Код, который я использовал для создания этого примера, является суперпростым. MainActivity.java выглядит:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClickButton(View v) {
        DatePickerDialog d = new DatePickerDialog(this, null, 2014, 5, 4);
        d.show();       
    }
}

И activity_main.xml выглядит:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onClickButton"
    android:text="Button" />
</RelativeLayout>


Это. Это действительно каждый код, который мне нужен, чтобы проверить это.

И это изменение выглядит кристально, когда вы видите исходный код платформы Android. Это выглядит так:  

public DatePickerDialog(Context context,
    OnDateSetListener callBack,
    int year,
    int monthOfYear,
    int dayOfMonth,
    boolean yearOptional) {
        this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
                ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
                : com.android.internal.R.style.Theme_Dialog_Alert,
        callBack, year, monthOfYear, dayOfMonth, yearOptional);
}

Как вы можете видеть, структура получает текущую targetSDKversion и устанавливает другую тему. Этот вид фрагмента кода (getApplicationInfo().targetSdkVersion >= SOME_VERSION) можно найти здесь и там в базе Android.

Другой пример - WebView class. В основном потоке должны быть вызваны общедоступные методы класса Webview, а если нет, система времени выполнения выбрасывает RuntimeException, когда вы устанавливаете targetSDKversion 18 или выше. Это поведение можно явно представить с помощью исходного кода. Это просто так написано.

sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
            Build.VERSION_CODES.JELLY_BEAN_MR2;

if (sEnforceThreadChecking) {
    throw new RuntimeException(throwable);
}


В документе Android говорится: "Поскольку Android развивается с каждой новой версией, некоторые изменения поведения и даже появление могут измениться". Итак, мы изменили поведение и внешний вид, и как это изменение выполняется.

В заключение, в документе Android говорится: "Этот атрибут (targetSdkVersion) сообщает системе, что вы протестировали против целевой версии, и система не должна включать поведение совместимости, чтобы поддерживать совместимость с Outlook с целевой версией". Это действительно ясно в случае с WebView. Это было нормально, пока JELLY_BEAN_MR2 не выпущен для вызова общедоступного метода класса WebView на не основной поток. Это вздор, если платформа Android создает исключение RuntimeException на устройствах JELLY_BEAN_MR2. Это просто не должно позволять вновь введенные поведения для его интереса, которые вызывают фатальный результат. Итак, что мы должны сделать, это проверить, все ли в порядке на определенные целевые значения. Мы получаем выгоду как улучшение внешнего вида с установкой более высокой targetSDKversion, но оно несет ответственность.

ИЗМЕНИТЬ: отказ от ответственности. Конструктор DatePickerDialog, который задавал разные темы, основанные на текущей targetSDKversion (что я показал выше), фактически был изменен в позже commit. Тем не менее я использовал этот пример, потому что логика не была изменена, и этот фрагмент кода четко показывает концепцию targetSDKversion.

  • 2
    «Мы получаем выгоду, например, улучшение внешнего вида, устанавливая более высокий уровень targetSDKversion, но это идет с ответственностью». Если бы они упомянули эту строку в документах, я бы не стал ее искать.
  • 0
    @ 김준호 У меня есть два вопроса: 1.) В приведенном выше примере выбора даты, если вы установили targetSdkVersion на 10 или ниже и запустили приложение на устройстве с последней версией Android (например, API 22), будет ли средство выбора даты по-прежнему отображаться как старое на левой картинке? 2. Означает ли это, что я всегда могу установить для targetSdkVersion любую версию, более высокую, чем моя minSdkVersion (например, чтобы получить такие улучшения пользовательского интерфейса, как этот хрустящий указатель даты из более высоких API) без необходимости какого-либо тестирования ( как такового ), пока я ограничиваю свою базу кода использовать только API, доступные в моем minSdkVersion?
Показать ещё 7 комментариев
21

Для тех, кто хочет резюме,

android:minSdkVersion

- минимальная версия, пока ваше приложение не поддерживает. Если ваше устройство имеет более низкую версию Android, приложение не будет установлено.

в то время,

android:targetSdkVersion

- уровень API, до которого ваше приложение предназначено для запуска. Значит, вашей телефонной системе не нужно использовать какие-либо совместимые beahviors для поддержки передовой совместимости, потому что вы протестировали против этого API. Кроме того, это позволяет использовать некоторые, но не все функции этой целевой версии.

Халява -

android:maxSdkVersion

если версия вашего устройства API выше, приложение не будет установлено. То есть. это максимальный API, до которого вы позволяете устанавливать приложение.

т. для MinSDK -4, maxSDK - 8, targetSDK - 8 Мое приложение будет работать минимум на 1.6, но я также использовал функции, которые поддерживаются только в 2.2, которые будут видны, если они установлены на устройстве 2.2. Кроме того, для maxSDK-8 это приложение не будет установлено на телефонах с использованием API > 8.

Меньшая ссылка

Разъяснение справки

  • 0
    'является максимальной версией, от которой ваше приложение унаследовало функции.' : это не верно. Это минимальная версия, от которой ваше приложение унаследовало функции - т.е. первая версия, которая включает в себя необходимые функции, используемые вашим приложением.
  • 0
    Английский язык хитрый. Прочитайте мой пример, приведенный в ответе. Я предполагаю, что у меня есть смысл там. :)
Показать ещё 1 комментарий
9

Если вы получаете некоторые ошибки компиляции, например:

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

.

private void methodThatRequiresAPI11() {
        BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Config.ARGB_8888;  // API Level 1          
                options.inSampleSize = 8;    // API Level 1
                options.inBitmap = bitmap;   // **API Level 11**
        //...
    }

Вы получаете ошибку компиляции:

Поле требует уровня API 11 (текущий минимум равен 10): android.graphics.BitmapFactory $Опции # inBitmap

Начиная со версии 17 Android Development Tools (ADT) есть одна новая и очень полезная аннотация @TargetApi, которая может исправить это очень легко. Добавьте его до метода, который содержит описание проблемы:

@TargetApi
private void methodThatRequiresAPI11() {            
  BitmapFactory.Options options = new BitmapFactory.Options();
      options.inPreferredConfig = Config.ARGB_8888;  // API Level 1          
      options.inSampleSize = 8;    // API Level 1

      // This will avoid exception NoSuchFieldError (or NoSuchMethodError) at runtime. 
      if (Integer.valueOf(android.os.Build.VERSION.SDK) >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        options.inBitmap = bitmap;   // **API Level 11**
            //...
      }
    }

Теперь нет ошибок компиляции , и он будет работать!

EDIT: это приведет к ошибке выполнения на уровне API ниже 11. На 11 или выше он будет работать без проблем. Поэтому вы должны быть уверены, что вы вызываете этот метод на пути выполнения, охраняемом проверкой версии. TargetApi просто позволяет вам скомпилировать его, но вы запускаете его на свой страх и риск.

  • 1
    Я смущен по этому поводу. Что произойдет, если вы позже запустите свое приложение в системе с SDK 10?
  • 0
    Он будет работать с оператором options.inBitmap, и приложение должно работать нормально.
1

android:minSdkVersion и android:targetSdkVersion оба являются значениями Integer, которые необходимо объявить в файле манифеста android, но оба имеют разные свойства.

android:minSdkVersion: Это минимально необходимый уровень API для запуска приложения Android. Если мы установим одно и то же приложение в более низкой версии API, появится ошибка парсера, и появится проблема с поддержкой приложения.

android:targetSdkVersion: Целевая версия sdk - установить целевой уровень API приложения. если этот атрибут не объявлен в манифесте, версия minSdk будет вашей версией TargetSdk. Это всегда так, что "приложение поддерживает установку на всех более высоких версиях API, объявленных как TargetSdk Version". Чтобы сделать приложение ограниченным, нам нужно объявить maxSdkVersion в нашем файле манифеста...

0

Если вы создаете приложения, для которых требуется опасные разрешения и установите targetSDK на 23 или выше, вы должны быть осторожны, Если вы не проверяете разрешения во время выполнения, вы получите SecurityException, и если вы используете код внутри блока try, например, открытую камеру, может быть сложно обнаружить ошибку, если вы не проверите logcat.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню