如何exclude不必要的so文件?这个问题的解决方案很简单,就是在build.gradle中加个配置而已。
less
packaging {
jniLibs.excludes.addAll(listOf(
"lib/arm64-v8a/xx.so",
"lib/armeabi-v7a/xx.so"
))
}
但是却在应用到我目前的项目中时,遇到了很多阻塞点。
一、背景是什么
我在使用Maven库的方式项目中引入了一个第三方的sdk,它包含了一个主库的so以及很多其他插件的so,目前我只需要使用主库就可以了,为了减少打包后的大小,我需要将其他不需要的插件库全部移除。
二、移除so库的过程
由于我引入的sdk是在Library模块中引入的,首先我在Library模块中做了exclude配置,分别尝试了packagingOptions(这个是旧的方式)和packaging,经过测试没有生效。
第一次闯关:将此问题抛给了AI去解决,AI给出的答案时,需要在应用Library模块中去配置才会生效,于是我将配置项移动到了主模块中,依然没有生效。
第二次闯关 :各种问AI,各种搜索解决方案,清除缓存,尝试不同的配置方式,折腾了许久还是没有解决。最后灵机一动,决定新建一个项目来做测试,先验证我们配置方式的正确性,这样一来就减少很多变量,使用一个测试项目来进行验证,项目由庞大变成轻量,加快了验证的过程,这次处理问题方式的转变也成了解决此问题的关键点。创建测试项目后,经过测试在主模块中使用相同的配置是有效,完全没有问题,为了保持和我们项目的一致性,我还创建一个了Library模块来测试,经过验证也是有效的,不过必须在主模块的build.gradle进行配置。
第三次闯关 :经过以上的验证,我确定了我们方式的正确性。但是应用到我们的项目,依然没有生效,再次陷入僵局中,于是由求助AI,分析各种原因,进行各种尝试,折腾了许久,依然没有进展。同事的一句提醒,也成了这次解决问题的关键,他说我们的方式肯定没有问题,为什么没有生效,那肯定是我们项目中有地方的配置级别更高,将我们的配置忽略了。于是我就从我们项目中去查找代码,看是否有地方在做这个配置,最后在搜索packaging关键字时找到了我们项目中确实有地方在做这个配置,位置是在build-logic中的application plugin代码中配置的。
markdown
packaging {
jniLibs {
pickFirsts += "lib/**/*.so"
}
}
第四次闯关:经过以上的探索,我找到了配置的地方,于是我充满信心地在对应的位置添加了exclude的配置。
arduino
packaging {
jniLibs {
excludes += "lib/**/xx.so"
pickFirsts += "lib/**/*.so"
}
结果大失所望,依然没有生效。求助AI后发现,我的配置并没有什么问题,那么问题就转向了exclude和pickFirsts的执行先后问题了,AI的回答是excludes的执行优先级最高,所以从配置上来看并没有什么问题。就在黔驴技穷的时候,我就想着,要不注释掉pickFirsts看看呢,没想到就是这次尝试,让问题得到了最终的解决。经过测试后,发现确实是pickFirsts的影响,根据此现象我查找了相关资料,得到了一个解释是:pickFirsts使用的通配符包含了所有的so文件,致使excludes失效,我们需要使用更精确的配置,pickFirsts后面最好是添加确定的so文件,不要使用 "lib/**/*.so"
这种广泛的通配符。我进一步查询了官方的文档,没有找到更详细的解释,AI也只是说这个结论是基于实际使用经验和社区讨论得出的。
最后我将配置方式进行了如下修改:
arduino
packaging {
jniLibs {
excludes += "lib/**/xxx.so"
// 如果没有冲突的so库,可以注释掉这里
pickFirsts += "lib/**/xx.so"
}
}
我们在项目中会遇到很多意想不到的问题,甚至无法找到合理的解释,就比如大家经常使用的重启电脑可以解决到许多问题一样。我们在做项目开发中很多问题也是无法找到正确的答案,至少是暂时找不到,需要更多,更专业的知识储备才能做出解释。那么我们遇到了又该怎么解决呢?我觉得第一个就是减少影响的变量,把影响结果的因素项降到最少,比如我们的项目不确定因素很多,我们可以新建一个项目,模拟相同的场景来进行测试;第二个我觉得尝试是很重要的,由过程推导结论有时候是很难的,但是由结论去反推过程会相对容易些,当我们经过尝试知道了答案和影响因素后,再去分析原因就要容易些。