边实验边分析-NDK篇-abiFilters配置分析

边实验边分析-NDK篇-abiFilters配置分析

首先我们需要了解一个行为,NDK会对我们的原生代码进行构建,针对不同的操作系统架构,生成不同的ABI(应用程序二进制接口)的so库,并将构建生成的so库打包到apk的lib目录下

默认情况下,cmake会构建x86_64,x86,arm64-v8a,armeabi-v7a四个架构的ABI(应用程序二进制接口),并打包这4个ABI的so库到apk中,这边会涉及到构建和打包2个行为,所以我们需要从这两个行为来分析该配置起到的作用

第一种方式我们可以通过指定模块级gradle中defaultConfig.ndk块的abiFilters来指定应该构建和打包哪些ABI在你的APK里

defaultConfig {
        ndk {
            abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
        }

这样指定后,构建方面则只会构建这三种架构的ABI

在这里插入图片描述
在打包方面,这个配置也会最终将这三个架构的so全部打包到apk中,通过build Analyze APK可以进行查看
在这里插入图片描述

第二种方式可以通過在模块级的gradle中配置defaultConfig.externalNativeBuild.cmake 块,添加abiFilters标记

defaultConfig {
        externalNativeBuild {
            cmake {
                abiFilters 'x86_64',
                        'arm64-v8a'
            }
        }
    }

这样,cmake在构建的时候只会去构建我们配置的这两个ABI
在这里插入图片描述

并生成so文件
在这里插入图片描述
在打包方面,也会打包这两个架构的so库到apk中

看起来,这两个配置没什么区别,其实这两个配置有很大的区别的

那么这两个配置的区别是什么呢?

区别还是在它们的构建和打包行为上,我们来具体分析一下
在第一个例子里我们只配置了ndk块而没配置externalNativeBuild块,那么externalNativeBuild块就会采用默认的值进行构建,默认的值会打包构建4种架构的ABI,但是由于我们使用ndk块限制了最终打包进入到apk里的只能是x86_64, armeabi-v7a, arm64-v8a这三个架构的ABI,所以在执行构建的时候,也只会执行这三个ABI的构建,这一点显的比较智能,不会进行多余的构建,可以看出来ndk块的控制点在最终的打包行为上

在第二个例子里,我们只配置externalNativeBuild块而不配置ndk块,那ndk块就会采用默认的值进行打包构建,默认的值就是需要将4种架构的ABI都打入apk内,但由于externalNativeBuild块只构建了x86_64, arm64-v8a,所以只会把这三个架构的ABI打入apk中,可以看出来externalNativeBuild块的控制点在初期的构建行为上

我们继续来分析另一个做法,这次我们使用第一个例子的ndk块的配置,并在我们的工程中放入其他的so库,如:
在这里插入图片描述
最终进入APK的会是这样
在这里插入图片描述
可以看出来,ndk块的配置不光会影响到我们自己构建的so库打包进入apk内,即如果你的工程包含了其他的so库,那么这些库也会受ndk块的配置的影响,如第一个例子里,其会打包x86_64, armeabi-v7a, arm64-v8a这三个架构进入apk,那么如果在我们没有其他库的时候,最终打包进入apk的只会是这三个架构的so文件,但我们如果放入其他的so库在我们的工程中,则会像上面的图示那样

接下来我们来分析一下,如果这两个配置我们都配置了会怎么样,
我们在模块级的gradle里配置

defaultConfig {
        externalNativeBuild {
            cmake {
                abiFilters 'x86_64', 'arm64-v8a'
            }
        }
        ndk {
            abiFilters 'x86_64', 'armeabi-v7a'
        }
    }

另外,为了方便说明,我们也加入其他的so库在我们的工程中
在这里插入图片描述

我们配置externalNativeBuild 块为构建 x86_64和arm64-v8a,配置ndk块为构建和打包x86_64和armeabi-v7a,他们有一个同样的x86_64架构,那么最终的行为会如何呢?
在这里插入图片描述
在这里插入图片描述
没错,只有构建了x86_64,可以看出来,是做了处理的,继续先看一下打包进apk会变成什么样子呢?

在这里插入图片描述
会变成这样,我们来分析一下,由于我们配置了ndk块,所以最终肯定只有打包我们配置的2个架构的ABI,x86_64和armeabi-v7a,但由于我们没有在externalNativeBuild 块构建armeabi-v7a,所以不会有armeabi-v7a的so,打包进入armeabi-v7a的so只可以是其他的so,这样我们就知道了其中的奥妙所在了。

最后,细心的朋友可能会说,其实还有一种情况,如果我externalNativeBuild 块和ndk块配置的ABI完全不一样,那会怎么样呢?
比如下面的配置

defaultConfig {
        externalNativeBuild {
            cmake {
                abiFilters 'x86_64', 'arm64-v8a'
            }
        }
        ndk {
            // Specifies the ABI configurations of your native
            // libraries Gradle should build and package with your APK.
            abiFilters 'x86', 'armeabi-v7a'
        }
    }

我们来尝试运行一下,会发现Gradle报错了
在这里插入图片描述
错误是No valid Native abi found to request! 很有道理啊,因为这样配置就是一个矛盾的结合体,当然不行。

总结一下,即externalNativeBuild块管的是构建原生代码的ABI,而ndk块管的是最终打包进入apk的ABI,而这两个属性相互之间又是有联系的,他们是可以混用的。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡卡爾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值