前言在Android开发过程中,有些功能是通用的,或者需要多个业务方共同使用。为了统一功能逻辑,避免重复开发,将此功能开发成SDK是很有必要的。背景我最近刚遇到类似的需求。开发SDK后,在集成到项目中或者提供给他人时遇到了一些坑。在此分享一下,免得其他需要开发SDK的开发者重蹈覆辙。文章内容如下:AAR集成方式比较集成方式的一些陷阱使用mavenpublish和maven推送SDK到maven仓库的区别。大约有3种类型的集成方法。1.提供Module的集成方法,将整个SDK的源代码提供给他人。优点:没有陷阱。只要自己测试一下,其他人就可以直接使用。缺点:如果以后有更新,需要全换别人。而且,如果项目中同时引用了多个模块,会在项目结构中增加很多代码文件。也有可能不小心更改了SDK。因为源代码可以直接修改,不需要任何保护。2.提供AAR文件这种集成方式是SDK编译好后,提供AAR文件给他人使用。优点:只有一个文件,不需要具体的源代码。缺点:在某些情况下会有陷阱,下面会提到。另外SDK更新不方便,每次更新都需要用户更换AAR文件。3.推送到仓库(这里我们以MAVEN仓库为例)(推荐)这种集成方式是将SDK编译好的AAR文件推送到仓库,然后可以通过实现或者api(老的)来引用Gradle的版本是编译)。优点:易于集成,类似于第三方库集成,方便开发者使用。还有版本管理。缺点:mavenpublish有坑。见下文分析。表格对比如下:集成方式的优缺点提供Module无坑维护麻烦,无代码保护提供AAR文件只有一个文件有坑,更新麻烦Push到仓库集成方便,版本管理mavenpublish有坑一些AAR集成方式的坑一般SDK开发都是为了方便调用封装一些功能,所以在Module中引入第三方库的情况比较少见。在这种情况下使用AAR集成不是什么大问题。但是当你的SDK中引入了第三方库,比如Retorfit(不是直接导入jar包或者aar包),这时候你使用AAR集成,在你使用的时候会提示java.lang.NoClassDefFoundError错误运行到相应的代码。这时候你明明运行Module没有问题,但是AAR却报错了。如果再次尝试将SDK使用的第三方库导入到项目中,会发现程序并没有报错。因此,我们可以得出结论,AAR不能中转第三方依赖,不用慌,方法永远比问题多。我们可以通过将SDK推送到存储库来解决这个问题。推送仓库有很多,比如开源的jcenter之类的。这里考虑到一些SDK是公司内部使用的,所以以maven为例进行说明。使用mavenpublish和maven推送SDK到maven仓库的区别mavenpublish其实是maven的升级。所以一般首选mavenpublish。本项目已经使用了mavenpublish,所以这边一开始也使用了mavenpublish。结果,坑来了。发现出现了和AAR一样的错误,无法传递依赖。现在,快速查看pom文件(与AAR同目录),发现确实没有依赖关系。查了网上资料。发现https://discuss.gradle.org/t/using-the-maven-publish-plugin-no-dependencies-in-pom-xml/7599有问题,当然应该有相应的处理方法,但是由于项目时间要求比较紧,又不想花太多时间,所以暂时没有找到解决办法。有知道的朋友可以留言,有空再跟踪研究,有解决办法会更新。所以这里不讨论mavenpublish的集成方式。最后用maven的push方法查了下资料。那么如何使用呢?1、先使用本地仓库,确定没有问题,再使用远程仓库。在Module的build.gradle文件中添加如下代码:applyplugin:'maven'//指定使用mavenuploadArchives{repositories{mavenDeployer{pom.groupId="com.maven.demo"//包名pom.artifactId="login"//SDK功能,可以自定义一个pom.version="0.0.1"//版本号repository(url:"file://localhost/Users/username/Library/Android/sdk/extras/android/m2repository/")//把用户名换成自己的机器名,本机地址}}}执行uploadArchives任务上报。然后进入上面url指定的目录或者通过浏览器打开就可以看到上传的相关文件了。查看pom文件,可以看到依赖都在上面了。2.使用远程仓库,对上面稍作修改。applyplugin:'maven'//指定使用mavenuploadArchives{repositories{mavenDeployer{pom.groupId="com.maven.demo"//包名pom.artifactId="login"//SDK函数,自定义一个pom.version="0.0.1"//版本号repository(url:"url"){authentication(userName:"username",password:"password")}}}}记得分别替换url,username和password。当其他人需要使用时,只需要在Module中添加如下内容:implementation'com.maven.demo.login.0.01',所以仓库的组成是pom.groupId+pom.artifactId+pom.versionTips:1.SDK开发可能会遇到同一个版本,比如0.0.1,发布前经常需要修改。此时如果将修改后的SDK推送到远程,本地项目可能还在使用旧的内容。有两种方法可以处理这种情况。第一个是更新版本号,修改取决于新版本。第二种是执行以下命令在不使用缓存的情况下强制从远程拉取。./gradlewbuild--refresh-dependencies2.使用远程仓库时,一般用户名和密码不会直接推送到代码仓库,可能会放在构建机上。这时候就需要使用一个类似local.properties的外部文件来存储。这时候有个坑需要提醒一下,就是在local.properties中定义比如maven_user_name=username,不要加双引号,否则会认证失败,会出现如下提示:Receivedstatuscode401fromserver:Unauthorized3.如何以maven的形式指定debug或release?可以通过在android块中添加android{defaultPublishConfig"release"}来指定。您可以通过查看Module的build/outputs/aar来查看aar包。查看Module的build/poms/pom-default.xml可以看到本地的pom文件。4、如果部分开发者按照上述操作后仍然报java.lang.NoClassDefFoundError错误,可以尝试如下操作:将implementation'com.maven.demo.login.0.01'修改为implementation'com.maven.demo.login。0.01'{transitive=true}总结1、SDK开发完成后,最好发布给别人使用,放在远程仓库(如maven)。2.如果出现找不到SDK引入的第三方库的错误,记得查看仓库中的pom文件是否有对应的依赖
