如何制作支持32位和64位架构的Android应用程序?

时间:2018-01-31 19:00:38

标签: android android-ndk google-play 64-bit 32-bit

我刚收到并阅读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的体系结构指南了解更多信息。

在适用的情况下,我们需要做出哪些实际更改才能完全符合此新要求?

12 个答案:

答案 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位设备。如果您的应用使用任何本机代码,或者不确定是否使用本机代码,则需要评估您的应用并采取措施。

您的应用是否使用本机代码?

要做的第一件事是检查您的应用程序是否使用任何本机代码。如果您的应用使用了本机代码,则:

  • 在您的应用中使用任何C / C ++(本机)代码。
  • 链接到任何第三方本地库。
  • 由使用本机库的第三方应用程序构建器构建。

有关更多信息,visit the docs

答案 3 :(得分:1)

如果您的Android APK不包含64位支持,则无需担心。 在Android Studio中转到“构建”->“分析APK”。您可以看到APK结构。在lib下,如果您看到https库,并且没有任何armeabi-v7aarm64-v8a库,则您的APK不支持64位体系结构。

只需进入应用程序级别x86_64并在build.gradle下的NDK中添加abiFilters,如下所示:

defaultConfig

答案 4 :(得分:1)

  • 选项1 -从APK中删除lib。
    • 第1步-将APK转换为ZIP并找到lib文件夹;如果您有lib文件夹,请参见库依赖项。
    • 第2步-从构建Gradle中删除依赖项。
  • 选项2 -下载64位和32位JAR文件,并将其添加到app的lib文件夹中并进行构建。

答案 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
        }
    }
}

Multi-Aks Attachment

答案 9 :(得分:0)

根据文档here,如果您的应用使用基于本机的本地代码或外部库(例如,下图所示的领域),则应提供对64位的支持。如果您的应用程序中使用任何C / C ++(本机)的任何外部库都应同时支持32位和64位体系结构,否则请与库所有者联系。在Android Studio中,我们可以通过构建>分析APK 来检查两种架构的版本是否可用

enter image description here

如果您正在使用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();