Как сделать приложения для Android, которые поддерживают как 32-битную, так и 64-битную архитектуру?
Я только что получил и прочитал новостную рассылку от Google Play, в которой говорится, что со следующего года магазин "потребует, чтобы новые приложения и обновления приложений с собственными библиотеками предоставляли 64-разрядные версии в дополнение к их 32-разрядным версиям".
Для тех, кто еще не читал это, говорится:
Требование поддержки 64-разрядных в 2019 году
Поддержка платформы для 64-битных архитектур была представлена в Android 5.0. Сегодня более 40% устройств Android, подключенных к сети, поддерживают 64-разрядную версию, при этом сохраняя 32-разрядную совместимость. Для приложений, которые используют собственные библиотеки, 64-битный код обычно предлагает значительно лучшую производительность с дополнительными регистрами и новыми инструкциями.
В ожидании будущих устройств Android, которые будут поддерживать только 64-битный код, для консоли Play потребуется, чтобы новые приложения и обновления приложений с собственными библиотеками предоставляли 64-битные версии в дополнение к их 32-битным версиям. Это может быть один APK или один из нескольких опубликованных APK.
Мы не удаляем 32-битную поддержку. Google Play продолжит поддерживать 32-битные приложения и устройства. Приложения, которые не содержат собственный код, остаются без изменений.
Это изменение вступит в силу в августе 2019 года. Сегодня мы предоставляем предварительное уведомление, чтобы предоставить разработчикам, которые еще не поддерживают 64-разрядную версию, достаточно времени для планирования перехода. Следите за будущими публикациями, в которых мы подробно рассмотрим преимущества производительности 64-битных собственных библиотек на Android и ознакомимся с руководством по процессорам и архитектурам NDK для получения дополнительной информации.
Какие практические изменения нам нужно будет сделать, чтобы полностью соответствовать этому новому требованию, когда это применимо?
1 ответ
Если у вас нет собственного (NDK) кода, то есть вы пишете только код Java / Dex, то вам не нужно ничего делать.
Если у вас есть собственный код (или библиотеки), вам нужно предоставить 64-битные версии.
Согласно официальному электронному письму, отправленному командой Google Play, необходимо выполнить следующие действия:
Если вы этого еще не сделали, мы рекомендуем вам как можно скорее начать работу над 64-разрядным требованием. Многие приложения написаны полностью не на нативном коде (например, язык программирования Java или Kotlin) и не нуждаются в изменениях кода.
Обратите внимание, что мы не вносим изменения в нашу политику в отношении 32-разрядной поддержки. Google Play продолжит доставлять приложения с 32-битным собственным кодом на 32-битные устройства. Требование означает, что эти приложения также должны иметь 64-битную версию.
Чтобы помочь вам осуществить переход, мы подготовили документацию о том, как проверить, поддерживает ли ваше приложение 64-разрядную версию и как стать 64-разрядной.
Мы также предоставляем график высокого уровня ниже.
Итак, связанная документация объясняет:
Если ваше приложение использует только код, написанный на языке программирования Java или Kotlin, включая любые библиотеки или SDK, ваше приложение уже готово для 64-разрядных устройств. Если ваше приложение использует какой-либо нативный код, или вы не уверены, что оно используется, вам необходимо оценить его и принять меры.
[...]
Самый простой способ проверить наличие 64-битных библиотек - проверить структуру вашего APK-файла. После сборки APK будет упакован с любыми встроенными библиотеками, необходимыми приложению. Собственные библиотеки хранятся в разных папках на основе ABI. Не требуется поддерживать каждую 64-разрядную архитектуру, но для каждой поддерживаемой вами 32-разрядной архитектуры необходимо включить соответствующую 64-разрядную архитектуру.
Для архитектуры ARM 32-битные библиотеки расположены в armeabi-v7a. 64-битный эквивалент - arm64-v8a.
Для архитектуры x86 ищите x86 для 32-битной и x86_64 для 64-битной.
Первое, что нужно сделать, это убедиться, что у вас есть собственные библиотеки в обеих этих папках.[...]
И, чтобы построить 64-битные библиотеки, вам нужно следовать инструкциям ниже:
Большинство проектов Android Studio используют Gradle в качестве базовой системы сборки, поэтому этот раздел относится к обоим случаям. Включение сборок для вашего нативного кода так же просто, как добавление arm64-v8a и / или x86_64, в зависимости от архитектуры, которую вы хотите поддерживать, в настройку ndk.abiFilters в файле build.gradle вашего приложения:
// Your app's build.gradle apply plugin: 'com.android.app' android { compileSdkVersion 27 defaultConfig { appId "com.google.example.64bit" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" ndk.abiFilters 'armeabi-v7a' 'arm64-v8a' 'x86' 'x86_64' // ...
Наконец, быстрое примечание:
64-битная версия вашего приложения должна иметь то же качество и набор функций, что и 32-битная версия.
В соответствии с приведенной здесь документацией, если ваше приложение использует собственный код или внешнюю библиотеку, например, область (на рисунке ниже), которая основана на собственном коде, то должна быть обеспечена поддержка 64-битной версии. если какая-либо из внешних библиотек в вашем приложении, использующая любой C/C++ (нативный), должна иметь поддержку как 32-битной, так и 64-битной архитектуры, в противном случае обратитесь к владельцу библиотеки. В Android studio мы можем проверить, доступны ли версии для обеих архитектур, с помощью Build > Analyze APK, появится следующее окно
если вы используете NDK и создаете собственный код, вы должны обеспечить поддержку обеих архитектур, включив их в Gradle как
defaultConfig {
ndk.abiFilters = 'armeabi-v7a' 'arm64-v8a' 'x86' 'x86_64'
}
Если ваш Android APK не поддерживает 64-разрядную версию, вам не о чем беспокоиться. Зайдите в Build -> Analyze APK в Android Studio. Вы можете увидеть структуру APK. Под lib, если вы видитеarmeabi-v7a
библиотеки и если у вас их нет arm64-v8a
или x86_64
библиотеки, то ваш APK не поддерживает 64-битную архитектуру.
Просто перейдите на уровень приложения build.gradle
и добавить abiFilters
в НДК под defaultConfig
как показано ниже:
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
Шаг 1:
app=> build.gradle (put below code in build.gradle)
android {
........
defaultConfig {
.........
ndk {
abiFilters = []
abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
}
........
}
.......
packagingOptions {
exclude 'lib/armeabi-v7a/libARM_ARCH.so'
}
}
Шаг 2
gradle.properties
(поместите строку ниже в gradle.properties)
PROP_APP_ABI=armeabi-v7a:arm64-v8a
Шаг 3: Создайте объект снова. Попробуйте загрузить этот apk в игровой магазин.
Добавление
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
в build.Gradle
файл под DefaultConfig
. Обратите внимание, что скоро появятся требования к 64-разрядной версии магазина push to play.
Я пробовал это Официальные документы Android. Работает отлично. В этом решении у меня есть сборка нескольких APK, которые вы можете увидеть во вложении... Убедитесь, что ваша версия компиляции Skd - 29 или версия инструментов сборки - 29.0.3 Написано ниже:
Android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "com.myapp.sk"
minSdkVersion 21
targetSdkVersion 29
versionCode 2
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
splits {
density {
enable true
reset()
include "mdpi", "hdpi"
}
abi {
enable true
reset()
include "x86", "x86_64"
}
}
}
// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3]
// For per-density APKs, create a similar map like this:
// ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3]
import com.android.build.OutputFile
// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->
// Assigns a different version code for each output APK
// other than the universal APK.
variant.outputs.each { output ->
// Stores the value of ext.abiCodes that is associated with the ABI for this variant.
def baseAbiVersionCode =
// Determines the ABI for this variant and returns the mapped value.
project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
// Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
// the following code does not override the version code for universal APKs.
// However, because we want universal APKs to have the lowest version code,
// this outcome is desirable.
if (baseAbiVersionCode != null) {
// Assigns the new version code to versionCodeOverride, which changes the version code
// for only the output APK, not for the variant itself. Skipping this step simply
// causes Gradle to use the value of variant.versionCode for the APK.
output.versionCodeOverride =
baseAbiVersionCode * 1000 + variant.versionCode
}
}
}
- Вариант 1 - удалить lib из APK.
- Шаг 1 - конвертируйте APK в ZIP и найдите папку lib; если у вас есть папка lib, см. зависимость библиотеки.
- Шаг 2 - удалите зависимость от сборки Gradle.
- Вариант 2 - Загрузите 64-разрядный и 32-разрядный файл JAR и добавьте его в папку lib в приложении и сборке.
В моем случае я использовал библиотеку (ESRI ArcGIS для Android), которая использует библиотеки OpenGL C. Вместоndk.abiFilters...
строка, которая, кажется, решает проблемы всех остальных, мне пришлось использовать следующее:
ndk { abiFilters "armeabi-v7a", "arm64-v8a" }
Сначала откройте приложение модуля build.gradle и добавьте эти строки, чтобы удалить файлы.so и добавить 64-битные лиобрарии, удалив все файлы.so, присутствующие в библиотеках apk
android {
compileSdkVersion 29
defaultConfig {
-----
-----
ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
packagingOptions{
packagingOptions {
exclude 'lib/armeabi-v7a/libvudroid.so'
exclude 'lib/x86/libvudroid.so'
exclude 'lib/arm64-v8a/libvudroid.so'
}
}`
Собственный код: относится к исполняемой программе, которая была скомпилирована непосредственно для инструкций ЦП компьютера, на котором она выполняется.
Неродной код: относится к исполняемой программе, которая была скомпилирована в инструкции ЦП исходной архитектуры Tandem конца 1970-х и 1980-х годов. Когда такая программа запущена, она не может выполняться непосредственно на процессоре компьютера, на котором она работает. Операционная система NonStop включает интерпретатор для этой исходной тандемной архитектуры, которая используется для запуска такого неродного кода.
Если ваше приложение использует только код, написанный на языке программирования Java или Kotlin, включая любые библиотеки или SDK, ваше приложение уже готово для 64-битных устройств. Если ваше приложение использует какой-либо собственный код или вы не уверены, что он использует, вам нужно будет оценить свое приложение и принять меры.
В вашем приложении используется собственный код?
Первое, что нужно сделать, это проверить, использует ли ваше приложение собственный код. Ваше приложение использует собственный код, если оно:
- использует любой (собственный) код C/C++ в вашем приложении.
- ссылки на любые сторонние собственные библиотеки.
- создается сторонним разработчиком приложений, использующим собственные библиотеки.
Подробнее см. В документации.