问题
当我们需要接入一些第三方的功能,常常需要引入第三方库。比较常见的,如极光推送,友盟分享等等。这些第三方往往产品比较成熟,接入的代价不高,侵入性小,不对已有项目的引用产生影响。除了这些,我们还会引入一些其他公司的库,接入一些必须的功能。但这些公司产品良莠不齐,所以我们就有必要对引入做出处理。
这里我分享一下我遇到的问题,至于这个包我就先屏蔽了,这个不是重点。OK。如图1,第三方给我的是一个.aar文件,我直接拷到了libs文件夹下面。在build之后,完美报错:
图1解决方案
我们可以看到在图1 报错的信息里面,涉及到了很多包名。既然跟包名有关,我们可以使用工具来观察一下这个aar包(这里我用7z打开了这个包)。
图2 aar包结构当然我们只关注classes.jar这个文件,跟包名冲突的问题一般都集中在这里面。我的项目里面没有集成jni部分,我们忽略。
图3 classes.jar包结构如图3可以看到有很多的包名,大部分都是第三方的。这时候我们再对照我们原有项目,可以发现我们原有项目引用的第三方库,很多的包名,跟里面的包名重复,对照图4,我们也可以发现报错的包名都是重复的包名。找到这部分重复引用的包,我们就可以简单粗暴的直接删除。
图4实际编译的时候 ,as也会在Run Task里面公布这些冲突的包名,如我们的图1。
图5 简单粗暴的删除可能有有人会说,我们可以用exclude关键字,根据包名来过滤这个东西。相比较而言,我个人觉得这样简单粗暴的使用,可能更加方便一点,特别对于急着发布的版本。当然我们也要防止对我们自己的项目产生影响,实际应用的时候要把功能测试完整(这是测试得工作)。免得项目出现文件缺失等,不该出现的错误。
做到这里,我以为改造完成了,因为在模拟器上面我已经能够正常的使用这个.aar里面的所有方法。然而在build手机上面的时候却还是报错
图6在图6中可以看到这些报错信息。我们先看最后一条错误NoSuchElementException,下面报错的位置也与我们自己的包名或者第三方的包名没有任何关系,往上也是。这种情况,一般跟项目本身没有关系。谷歌的gradle 3.0是默认android.enableAapt2 =true。但是给我发的这个第三方.aar文件是使用gradle 2.0编译的android.enableAapt2 =false。这里我们先给它置为false。至此,项目顺利编译完成(android.enableAapt2 这个方法as计划在2018年内取消,建议所有的项目都升级到gradle 3.0为免以后遇到问题)。
总结
理一理整个的引入过程,导入第三方的.aar文件,实际上就是一个组件化的过程。我们不关注组件化的内部的实现,只是单纯的引入.aar包文件的功能。使用api依赖或者 导入.aar包引入的方式,如果没有提前沟通,必然会有冲突产生。除了包名的冲突,还会有其的问题。所以要引用这种第三方扩展功能,我们有必要在引入之前做一些限制,如:共通的第三方资源库。通过共通的这个库来约束大家如果使用相同的引用,就必须保证版本的一致性。如果大家需要了解更多这方面的内容,可以搜索“安卓组件化开发”来了解一下。
网友评论