Минимальная версия Android SDK против целевой версии SDK
Когда речь идет о разработке приложений для Android, в чем разница между версией Min и Target SDK? Eclipse не позволит мне создать новый проект, если версии Min и Target не совпадают!
9 ответов
андроид:minSdkVersion
Целое число, обозначающее минимальный уровень API, необходимый для запуска приложения. Система Android не позволит пользователю установить приложение, если уровень API системы ниже значения, указанного в этом атрибуте. Вы должны всегда объявлять этот атрибут.
андроид:targetSdkVersion
Целое число, обозначающее уровень API, на который нацелено приложение.
С этим установленным атрибутом приложение говорит, что оно может работать на более старых версиях (вплоть до minSdkVersion), но было явно протестировано на работу с указанной здесь версией. Указание этой целевой версии позволяет платформе отключить параметры совместимости, которые не требуются для целевой версии (которые в противном случае могут быть включены для обеспечения прямой совместимости), или включить новые функции, которые недоступны для более старых приложений. Это не означает, что вы можете программировать различные функции для разных версий платформы - это просто сообщает платформе, которую вы протестировали на целевой версии, и платформа не должна выполнять никаких дополнительных действий для обеспечения прямой совместимости с целевой версией.
Для получения дополнительной информации обратитесь к этому URL:
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
Комментарий ОП к этому вопросу (в основном утверждающий, что targetSDK не влияет на компиляцию приложения) абсолютно неверен! Извините за грубость.
Вкратце, вот цель объявления другого targetSDK из minSDK: это означает, что вы используете функции из SDK более высокого уровня, чем ваш минимум, но вы обеспечили обратную совместимость. Другими словами, представьте, что вы хотите использовать функцию, которая была только недавно представлена, но это не критично для вашего приложения. Затем вы должны установить targetSDK на версию, в которой была представлена эта новая функция, а минимальную - на более низкую, чтобы все могли по-прежнему использовать ваше приложение.
В качестве примера, скажем, вы пишете приложение, которое широко использует обнаружение жестов. Тем не менее, каждая команда, которая может быть распознана жестом, также может быть выполнена кнопкой или из меню. В этом случае жесты - это "круто", но они не обязательны. Поэтому вы должны установить целевой sdk на 7 ("Eclair", когда была представлена библиотека GestureDetection), а минимальный SDK - на уровень 3 ("Cupcake"), чтобы даже люди с действительно старыми телефонами могли использовать ваше приложение. Все, что вам нужно сделать, это убедиться, что ваше приложение проверило версию Android, на которой оно работало, прежде чем пытаться использовать библиотеку жестов, чтобы не пытаться использовать ее, если она не существует. (По общему признанию, это устаревший пример, так как вряд ли у кого-то все еще есть телефон v1.5, но было время, когда поддержание совместимости с v1.5 было действительно важно.)
Чтобы привести другой пример, вы можете использовать это, если вы хотите использовать функцию от Gingerbread или Honeycomb. Некоторые люди получат обновления в ближайшее время, но многие другие, особенно со старым оборудованием, могут застрять в Eclair, пока не купят новое устройство. Это позволило бы вам использовать некоторые интересные новые функции, но не исключая часть вашего возможного рынка.
В блоге разработчика Android есть действительно хорошая статья о том, как использовать эту функцию, и, в частности, о том, как разработать код "проверьте, существует ли функция перед ее использованием", о котором я упоминал выше.
ОП: Я написал это в основном для тех, кто случайно наткнется на этот вопрос в будущем, так как я понимаю, что ваш вопрос задавался давно.
Когда вы устанавливаете targetSdkVersion="xx", вы подтверждаете, что ваше приложение работает должным образом (например, было тщательно и успешно протестировано) на уровне API xx.
Версия Android, работающая на уровне API выше xx, будет автоматически применять код совместимости для поддержки любых функций, на которые вы могли полагаться, которые были доступны на уровне API xx или ранее, но которые сейчас устарели на более высоком уровне этой версии Android.
И наоборот, если вы используете какие-либо функции, которые устарели на уровне или до уровня xx, код совместимости не будет автоматически применяться версиями ОС на более высоких уровнях API (которые больше не включают эти функции) для поддержки этих применений. В этой ситуации в вашем собственном коде должны быть специальные предложения, которые проверяют уровень 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, напротив, устанавливает требование, чтобы версия ОС устройства имела как минимум этот уровень API для запуска вашего приложения. Это влияет на то, какие устройства могут видеть и загружать ваше приложение, когда оно находится в магазине приложений Google Play (и, возможно, также в других магазинах приложений). Это способ заявить, что ваше приложение опирается на функции ОС (API или других), которые были установлены на этом уровне, и не имеет приемлемого способа справиться с отсутствием этих функций.
Примером использования minSdkVersion для обеспечения наличия функции, не связанной с API, может быть установка minSdkVersion на 8, чтобы гарантировать, что ваше приложение будет работать только на JIT-версии интерпретатора Dalvik (так как JIT был представлен интерпретатору Android на уровне API 8). Поскольку производительность интерпретатора с поддержкой JIT может быть в пять раз выше, чем у той, у которой отсутствует эта функция, если ваше приложение интенсивно использует процессор, вам может потребоваться API уровня 8 или выше для обеспечения адекватной производительности.
Концепцию всегда лучше представить на примерах. У меня были проблемы с пониманием этой концепции, пока я не копался в исходном коде фреймворка Android и не проводил некоторые эксперименты, даже после прочтения всех документов на сайтах разработчиков Android и в связанных потоках stackru. Я приведу два примера, которые очень помогли мне полностью понять эти концепции.
DatePickerDialog будет выглядеть по-разному в зависимости от уровня, который вы поместили в targetSDKversion файла AndroidManifest.xml (<uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>
). Если вы установите значение 10 или ниже, ваш DatePickerDialog будет выглядеть как слева. С другой стороны, если вы установите значение 11 или выше, DatePickerDialog будет выглядеть правильно с тем же кодом.
Код, который я использовал для создания этого примера, очень прост. 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. Публичные методы класса Webview должны вызываться в главном потоке, а если нет, система времени выполнения выдает RuntimeException
, когда вы установите targetSDKversion 18 или выше. Это поведение может быть ясно предоставлено с его исходным кодом. Просто так написано.
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
if (sEnforceThreadChecking) {
throw new RuntimeException(throwable);
}
Документ для Android гласит: " По мере развития Android с каждой новой версией некоторые виды поведения и даже внешний вид могут меняться ". Итак, мы посмотрели, как изменилось поведение и внешний вид, и как это изменение произошло.
Таким образом, документ Android говорит: " Этот атрибут (targetSdkVersion) информирует систему, которую вы протестировали с целевой версией, и система не должна разрешать какие-либо поведения совместимости, чтобы поддерживать прямую совместимость вашего приложения с целевой версией ". Это действительно ясно в случае с WebView. Это было нормально, пока JELLY_BEAN_MR2 не был выпущен для вызова открытого метода класса WebView в неосновном потоке. Это бессмысленно, если платформа Android создает исключение RuntimeException на устройствах JELLY_BEAN_MR2. Это просто не должно включать вновь введенные поведения для его интереса, которые приводят к фатальному результату. Итак, что нам нужно сделать, это проверить, все ли в порядке на определенных targetSDKversions. Мы получаем выгоду, например, улучшение внешнего вида, устанавливая более высокий уровень targetSDKversion, но это идет с ответственностью.
РЕДАКТИРОВАТЬ: отказ от ответственности. Конструктор DatePickerDialog, который устанавливает различные темы на основе текущего targetSDKversion(который я показал выше), фактически был изменен в последующем коммите. Тем не менее, я использовал этот пример, потому что логика не изменилась, и этот фрагмент кода ясно демонстрирует концепцию targetSDKversion.
Для тех, кто хочет резюме,
android:minSdkVersion
минимальная версия, пока ваше приложение не поддерживает. Если на вашем устройстве установлена более низкая версия Android, приложение не будет установлено.
в то время как,
android:targetSdkVersion
это уровень API, до которого должно работать ваше приложение. Значит, системе вашего телефона не нужно использовать какие-либо способы обеспечения совместимости, чтобы поддерживать прямую совместимость, потому что вы тестировали до этого API.
Ваше приложение все еще будет работать на версиях Android выше, чем указано targetSdkVersion
но поведение совместимости андроида сработает.
Халява -
android:maxSdkVersion
Если версия API вашего устройства выше, приложение не будет установлено. То есть. это максимальный API, до которого вы разрешаете устанавливать приложение.
то есть. для MinSDK -4, maxSDK - 8, targetSDK - 8 Мое приложение будет работать на минимальной версии 1.6, но я также использовал функции, которые поддерживаются только в 2.2, которые будут видны, если оно установлено на устройстве 2.2. Кроме того, для maxSDK - 8 это приложение не будет устанавливаться на телефоны с API > 8.
На момент написания этого ответа документация по Android не очень хорошо объясняла его. Теперь это очень хорошо объяснено. Проверьте это здесь
Если вы получаете некоторые ошибки компиляции, например:
<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$Options#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**
//...
}
}
Нет ошибок компиляции сейчас, и он будет работать!
РЕДАКТИРОВАТЬ: Это приведет к ошибке времени выполнения на уровне API ниже 11. На 11 или выше он будет работать без проблем. Поэтому вы должны быть уверены, что вызываете этот метод на пути выполнения, защищенном проверкой версии. TargetApi просто позволяет вам скомпилировать его, но вы делаете это на свой страх и риск.
android:minSdkVersion
а также android:targetSdkVersion
оба являются целочисленными значениями, которые мы должны объявить в файле манифеста Android, но оба имеют разные свойства.
android:minSdkVersion:
Это минимально необходимый уровень API для запуска приложения для Android. Если мы установим то же приложение на более низкую версию API, появится ошибка синтаксического анализатора, и возникнет проблема не поддерживаемого приложения.
android:targetSdkVersion:
Target sdk version - установить уровень API приложения Target. если этот атрибут не объявлен в манифесте, версия minSdk будет вашей версией TargetSdk. Это всегда верно, что "установка поддержки приложения на все более высокие версии API мы объявили как TargetSdk Version". Чтобы сделать приложение ограниченным, нам нужно объявить maxSdkVersion в нашем файле манифеста...
Target sdk - это версия, на которую вы хотите нацелиться, а min sdk - минимальная.
Если вы создаете приложения, для которых требуются опасные разрешения, и для targetSDK установлено значение 23 или выше, вам следует быть осторожным. Если вы не проверяете разрешения во время выполнения, вы получите исключение SecurityException, и если вы используете код внутри блока try, например, открыть камеру, может быть сложно обнаружить ошибку, если вы не проверите logcat.