我刚收到并阅读a newsletter from Google Play提到从明年开始,商店“将要求使用本机库的新应用和应用更新除了32位版本之外还提供64位版本”
对于尚未阅读的人,请说明:
2019年的64位支持要求
Android中引入了对64位体系结构的平台支持 5.0。今天,超过40%的在线Android设备具有64位支持,同时仍保持32位兼容性。适用于那些应用 使用本机库,64位代码通常提供显着 更好的性能,附加寄存器和新指令。
期待未来支持64位代码的Android设备 只有,Play控制台才会要求新的应用和应用更新 本机库除了提供32位版本外,还提供64位版本 版本。这可以在单个APK内,也可以是多个APK中的一个 APK已发布。
我们不会删除32位支持。 Google Play将继续推出 支持32位应用程序和设备。不包含本机代码的应用 不受影响。
此更改将于2019年8月生效。我们正在提供 今天提前通知,以便为没有这样做的开发人员留出足够的时间 但支持64位计划过渡。请继续关注未来 我们将深入了解性能优势的帖子 Android上的64位本机库,并检查CPU和 NDK的体系结构指南了解更多信息。
在适用的情况下,我们需要做出哪些实际更改才能完全符合此新要求?
答案 0 :(得分:8)
根据Google Play小组发送的正式电子邮件,需要采取的措施是:
如果您还没有的话,我们建议您开始使用64位 要求尽快。许多应用都是完全用 非本机代码(例如Java编程语言或Kotlin)和 不需要更改代码。
请注意,我们不会更改32位政策 支持。 Google Play将继续提供32位本机应用程序 代码到32位设备。该要求意味着这些应用将 还需要具有64位版本。
为了帮助您进行过渡,我们已经准备了documentation 检查您的应用程序是否已经支持64位以及如何成为 符合64位。
我们还在下面提供了一个高级时间表。
因此,链接的文档说明:
如果您的应用仅使用以Java编程语言或 Kotlin,包括所有库或SDK,您的应用已准备就绪 64位设备。如果您的应用使用任何本机代码,或者您不确定 确实如此,您将需要评估您的应用并采取行动。
[...]
检查64位库的最简单方法是检查 APK文件的结构。构建后,APK将与 应用程序所需的任何本机库。本机库存储在 基于ABI的各种文件夹。不需要支持每个 64位架构,但是对于每个本机32位架构, 支持,您必须包括相应的64位体系结构。
对于ARM体系结构,32位库位于 armeabi-v7a。等效的64位是arm64-v8a。
对于x86体系结构,为32位寻找x86,为32位寻找x86_64。 64位。
要做的第一件事是确保您在两个目录中都具有本机库 这些文件夹。[...]
并且,要构建64位库,您基本上需要遵循以下说明:
大多数Android Studio项目使用Gradle作为基础构建 系统,因此本节适用于两种情况。启用构建 您的本机代码就像添加arm64-v8a和/或x86_64一样简单, 根据您希望支持的架构, 应用程序的“ build.gradle”文件中的ndk.abiFilters设置:
// 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位版本。
答案 1 :(得分:7)
如果您没有本机(NDK)代码,那就是您只编写Java / Dex代码,那么您不需要做任何事情。
如果您有本机代码(或库),则需要提供其64位版本。
答案 2 :(得分:1)
本机代码:是指直接编译为正在运行的计算机的CPU指令的可执行程序。
非本机代码:是指一种可执行程序,已编译为1970年代末和1980年代末原始Tandem体系结构的CPU指令。当运行这样的程序时,它不能直接在运行它的计算机的CPU上执行。 NonStop操作系统包含用于该原始Tandem体系结构的解释器,该解释器用于运行此类非本机代码。
如果您的应用仅使用以Java编程语言或Kotlin编写的代码(包括任何库或SDK),则您的应用已准备好用于64位设备。如果您的应用使用任何本机代码,或者不确定是否使用本机代码,则需要评估您的应用并采取措施。
您的应用是否使用本机代码?
要做的第一件事是检查您的应用程序是否使用任何本机代码。如果您的应用使用了本机代码,则:
有关更多信息,visit the docs。
答案 3 :(得分:1)
如果您的Android APK不包含64位支持,则无需担心。
在Android Studio中转到“构建”->“分析APK”。您可以看到APK结构。在lib下,如果您看到https
库,并且没有任何armeabi-v7a
或arm64-v8a
库,则您的APK不支持64位体系结构。
只需进入应用程序级别x86_64
并在build.gradle
下的NDK中添加abiFilters
,如下所示:
defaultConfig
答案 4 :(得分:1)
答案 5 :(得分:1)
首先打开build.gradle模块应用程序并添加以下行,以删除.so文件并添加64位库 删除apk库中存在的所有.so文件
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'
}
}`
答案 6 :(得分:1)
就我而言,我使用的库(使用ESRI ArcGIS for Android)利用了OpenGL C库。我不得不使用以下内容来代替似乎可以解决其他所有人问题的ndk.abiFilters...
字符串:
ndk { abiFilters "armeabi-v7a", "arm64-v8a" }
答案 7 :(得分:1)
第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到商店。
答案 8 :(得分:1)
我尝试通过官方Android Docs进行此操作。做工出色。 在此解决方案中,我有Build Multi APKs,您可以在附件中看到... 确保您的编译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
}
}
}
答案 9 :(得分:0)
根据文档here,如果您的应用使用基于本机的本地代码或外部库(例如,下图所示的领域),则应提供对64位的支持。如果您的应用程序中使用任何C / C ++(本机)的任何外部库都应同时支持32位和64位体系结构,否则请与库所有者联系。在Android Studio中,我们可以通过构建>分析APK 来检查两种架构的版本是否可用
如果您正在使用NDK并创建本机代码,则应通过在gradle中将它们注册为
来为这两种体系结构提供支持defaultConfig {
ndk.abiFilters = 'armeabi-v7a' 'arm64-v8a' 'x86' 'x86_64'
}
答案 10 :(得分:0)
添加
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
在build.Gradle
下的DefaultConfig
文件中。请注意,即按即用存储64位要求即将到来。
答案 11 :(得分:0)
将此添加到您的build.gradle
var xhr = $.ajax({
method: "POST",
url: "/MyReallySlowReport",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
// abort the request
xhr.abort();