平时开发中会把一些独立的功能模块抽取出来作为sdk,既方便业务接入,又能让其他业务线快速复用。那么我们就需要将sdk打包上传到maven仓库,让业务侧依赖即可。

一、编译后的产物

在上传产物到maven仓库之前,我们的知道产物到底是什么。

Android Gradle插件根据项目gradle中应用不同的插件类型在编译组装后会生成不同的产物:

1.1 APK 构件

Android项目的主工程app的gradle配置文件依赖:

apply plugin: 'com.android.application' 

因此,在通过编译命令./gradlew assembleDebug./gradlew assembleRelease后,就会在build/outputs/apk文件下生成产物:

如图,apk就是产物(构件)。

1.2 AAB(Android app bundle)构件

如果是海外市场,在Google Play上架的应用必须要打aab包,而不是之前的apk格式。具体区别就暂不讨论了~ 编译命令为:./gradlew bundleDebug./gradlew bundleRelease。产物为:

1.3 AAR 构件

一般的module在编译打包后,会生成aar:

二、publish插件

有了产物,我们就需要把产物上传到maven仓库(一般是私有仓库),方便公司项目直接依赖。而上传就要用到publish插件。APG 3.6.0之前用的maven插件,之后都用maven-publish插件。

2.1 maven-publish插件使用

我们可以新建一个gradle文件,如:maven_publish.gradle。专门用来上传aar。配置如下:

 //maven-publish 新方式
plugins {
    //todo 1 上传插件
    id 'maven-publish'
afterEvaluate{
    publishing {
        publications {
            // Creates a Maven publication called "myPublication".
            myPublication(MavenPublication) {
                groupId 'com.sdk.aarpub'
                artifactId 'aar-test'
                version '1.2.2'             // Your package version
//                artifact publishArtifact    //Example: *./target/myJavaClasses.jar*
                artifact "build/outputs/aar/aar-test-release.aar"//aar包的目录
                //带上依赖 ,否则会报错
                pom.withXml {
                    def dependenciesNode = asNode().appendNode('dependencies')
                    def scopes = [configurations.compile]
                    if (configurations.hasProperty("api")) {
                        scopes.add(configurations.api)
                    if (configurations.hasProperty("implementation")) {
                        scopes.add(configurations.implementation)
                    if (configurations.hasProperty("debugImplementation")) {
                        scopes.add(configurations.debugImplementation)
                    if (configurations.hasProperty("releaseImplementation")) {
                        scopes.add(configurations.releaseImplementation)
//                    if (project.ext.targetType != "jar") {
//                        scopes.add(configurations.provided)
//                    }
                    scopes.each { scope ->
                        scope.allDependencies.each {
                            if (it instanceof ModuleDependency) {
                                boolean isTransitive = ((ModuleDependency) it).transitive
                                if (!isTransitive) {
                                    println "<<<< not transitive dependency: [${it.group}, ${it.name}, ${it.version}]"
                                    return
                            if (it.group == "${project.rootProject.name}.libs" || it.version == 'unspecified') {
                                return
                            if (it.group && it.name && it.version) {
                                def dependencyNode = dependenciesNode.appendNode('dependency')
                                dependencyNode.appendNode('groupId', it.group)
                                dependencyNode.appendNode('artifactId', it.name)
                                dependencyNode.appendNode('version', it.version)
                                dependencyNode.appendNode('scope', scope.name)
        // Repositories *to* which Gradle can publish artifacts
        repositories {
            maven {
            //上传到项目本地仓库
                url uri('../local_mavenrepo')
//            credentials {
//                username "default"
//                password "default"
//            }

在assemble命令后,执行publish命令:

./gradlew publish 

2.2 maven插件使用

plugins {
    //todo 1 上传插件
    id 'maven'
uploadArchives{
    // 方式一
    repositories {
        mavenDeployer{
            repository(url: uri('../local_mavenrepo'))
            //todo 2 配置版本信息 方式二
            pom.groupId = 'com.sdk.aarpub'
            pom.artifactId = 'aar-test'
            pom.version = '1.1.0'
        //mavenLocal 这个是本机上的maven本地缓存仓库
//        mavenLocal()

在assemble命令后,执行uploadArchives命令:

./gradlew uploadArchives 

2.3 业务侧使用

在项目的根gradle文件中,配置仓库:

maven { url '../local_mavenrepo/'} 

在对应的模块中引入依赖:

implementation 'com.sdk.aarpub:aar-test:1.2.2' 

三、问题总结

3.1 项目中依赖本地aar的时候打包报错Direct local .aar file dependencies are not supported when building an AAR…

原因:当打包aar时候直接依赖本地的aar是不被允许的。 解决方案:通过把依赖的aar放到单独的模块中,让直接依赖本地aar变成依赖模块。

  1. 新建一个文件夹aar-lib
  2. 新建一个libs文件夹,把oaid_sdk_1.0.30.aar放入到libs目录中

image.png 3. 新建build.gradle文件,写入如下内容

configurations.maybeCreate("default")
def publishArtifact = artifacts.add("default", file('libs/oaid_sdk_1.0.30.aar')) 
  1. 在项目的settings文件中引入该模块
include ':aar-lib' 
  1. 删除报错模块中的aar文件,替换原来依赖方式
//    implementation files('libs/oaid_sdk_1.0.30.aar') 旧的方式
    implementation project(path:":aar-lib") 

3.2 module打包aar时依赖aar导致的类引用不到的问题

3.1 只是解决了在项目打包过程中依赖本地aar的问题。 当module作为sdk同时又依赖aar时,此时接入sdk会报错,提示引用不到aar中的类。当然我们可以直接把aar给到业务测,直接引入即可,但这样增加了接入成本。因此,我们的解决方案跟原理跟3.1一样,但是会把aar上传到远程库,作为远程来依赖。

比如 A模块依赖了oaid_sdk_1.0.30.aar,同时A模块作为sdk是要提供给业务侧app使用的。

  1. 按照3.1的方式创建一个aar-lib,build.gradle内容有所不同:
plugins {
    id 'maven-publish'
//生成文档注释
task androidJavadocs(type: Javadoc) {
    failOnError = false
    source = android.sourceSets.main.java.srcDirs
    ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
    classpath += files(ext.androidJar)
//将文档打包成jar
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    archiveClassifier.set('javadoc')
    from androidJavadocs.destinationDir
//将源码打包,这一点对kotlin来说很重要,否则业务侧无法看到源码
task androidSourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    from android.sourceSets.main.java.srcDirs
configurations.maybeCreate("default")
def publishArtifact = artifacts.add("default", file('libs/oaid_sdk_1.0.30.aar'))
afterEvaluate{
    publishing {
        publications {
            myPublication(MavenPublication) {
                groupId 'com.sdk.aarpub'
                artifactId 'aar-lib'
                version '1.0.0'             // Your package version
                artifact(androidSourcesJar)//将源码打包进aar,如果不需要可以去掉
                artifact(androidJavadocsJar)//将注释打包进aar,如果不需要可以去掉
                // 将aar推送到远程仓库
                artifact publishArtifact    //Example: *./target/myJavaClasses.jar*
        // Repositories *to* which Gradle can publish artifacts
        repositories {
            maven {
                url uri('../local_maverepo')
//            credentials {
//                username "default"
//                password "default"
//            }
  1. 执行发布命令
./gradlew :aar-lib:publish 
  1. 让A模块依赖第二步中推送到远程的aar库
implementation 'com.sdk.aarpub:aar-lib:1.0.0' 
  1. 重新打包A模块,当app依赖A模块时候,A模块中的aar就会被引用到了

当然在A模块发布的时候记得要带上依赖:

 //带上依赖 ,否则会报错
                pom.withXml {
                    def dependenciesNode = asNode().appendNode('dependencies')
                    def scopes = [configurations.compile]
                    if (configurations.hasProperty("api")) {
                        scopes.add(configurations.api)
                    if (configurations.hasProperty("implementation")) {
                        scopes.add(configurations.implementation)
                    if (configurations.hasProperty("debugImplementation")) {
                        scopes.add(configurations.debugImplementation)
                    if (configurations.hasProperty("releaseImplementation")) {
                        scopes.add(configurations.releaseImplementation)
//                    if (project.ext.targetType != "jar") {
//                        scopes.add(configurations.provided)
//                    }
                    scopes.each { scope ->
                        scope.allDependencies.each {
                            if (it instanceof ModuleDependency) {
                                boolean isTransitive = ((ModuleDependency) it).transitive
                                if (!isTransitive) {
                                    println "<<<< not transitive dependency: [${it.group}, ${it.name}, ${it.version}]"
                                    return
                            if (it.group == "${project.rootProject.name}.libs" || it.version == 'unspecified') {
                                return
                            if (it.group && it.name && it.version) {
                                def dependencyNode = dependenciesNode.appendNode('dependency')
                                dependencyNode.appendNode('groupId', it.group)
                                dependencyNode.appendNode('artifactId', it.name)
                                dependencyNode.appendNode('version', it.version)
                                dependencyNode.appendNode('scope', scope.name)

要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓

作为Android开发,在我们开发到一定阶段总会接触SDK开发、组件化开发,这样就会有组件发布Aar的需求。Gradle提供了maven-publish插件供我们完成组件发布需求,但是大多数人可能只是简单的使用,见葫芦画瓢,并没有完整的了解插件的作用。这里本着复习完善的想法,带大家一起好好学习下。... 原因:当打包aar时候直接依赖本地的aar是不被允许的。解决方案:通过把依赖的aar放到单独的模块中,让直接依赖本地aar变成依赖模块。新建一个文件夹aar-lib新建一个libs文件夹,把放入到libs目录中3. 新建build.gradle文件,写入如下内容在项目的settings文件中引入该模块删除报错模块中的aar文件,替换原来依赖方式// implementation files('libs/oaid_sdk_1.0.30.aar') 旧的方式。 现在App开发模块化技术已是常态,有很多的功能模块都被抽出来供给开发者使用。为了开发者使用,这些模块都会被打包,就和java中的库一样。在java中,一个模块可以被打包为Jar包,而在Android中,不仅仅有java文件,还有一些其他的资源文件,所以就出现了AAR文件(一种打包格式),本文通过一个demo来介绍如何打包一个Library文件,生成AAR。 文章目录maven-publish插件maven-publish使用引入插件使用插件publicaionsrepositioriespublishToMavenLocal完整的example maven-publish插件 maven-publish是一个Gradle插件,可以我们的编译的输出物(artifacts)发布到Apache Maven仓库当中,例如aar,jar等library发布... 一、maven-publish介绍   在 Gradle 1.3 中,引入了一种新的发布机制。这种新机制引入了一些新概念和功能,这些功能使 Gradle 发布变得更加强大,现在已成为发布工件的首选选项。 二、maven-publish使用 1、在build.gradle 声明插件 plugins { id 'maven-publish' 2、使用publishing{}块进行配置 group = 'org.example' version = '1.0' publishing. maven插件适用于gradle1.0-6.2版本,6.2版本后该插件就被废弃了,推荐使用maven-publish插件maven-publis插件是在gradle 1.3 版本后开始支持的,使配置更加简洁。 AndroidStudio使用maven-publish发布aarmavencentral中央仓库 1. 注册【sonatype】账号 2. 创建Group ID 3. 下载安装gnupg 4. 创建生成密钥 5. 配置maven-publish打包推送aar 6. 发布mavencen 如果你刚好把AndroidStudio升级到Android Studio Arctic Fox版本,刚好想新建一个工程来编写自定义Gradle插件,你就会发现你掉坑里了(没错,就是笔者本人了!),噩梦从此开始,一切都是因为你新建的工程中Gradle及其插件的版本已经默认是7.0及以上了。惊喜不惊喜,意外不意外?升级一时爽,填坑两行泪。 本文基于Android Studio操作,借助Gradle插件 —— Maven Publish,实现在构建完安卓库或者纯Java库之后,自动将之部署aar或jar至maven仓库,使其成为一个公共模块,供其他项目引用。 首先了解一下其他的多模块开发方法。 第一种:在setting.gradle中定义子模块然后 api Project(':...')),直接引用 。 第二种,部署至远程服务器,如 jitpack.io(傻瓜式操作,还支持gitee) 第一种方法适合小库,优点是改动后可一键构建运行,缺点是 如果自己开发的库想给别的项目用,需要把自己的库打包后上传到maven,最后每个项目只要依赖maven库就可以集成,maven插件已经过时,官方推荐使用maven-publish插件来实现将我们的代码发布到 Apache Maven仓库的功能。 apply plugin: 'maven-publish' 三、publish Task 所有以下任务都归在名为publishing类型为PublishingExtension的扩展下。 generatePomFileForPubNamePub configurations.maybeCreate("default") artifacts.add("default", file('demolibSDK_release.aar')) build.gradle(Module:app) dependencie... —START— 一、插件简介 maven-publish是一个Gradle插件,用来实现将本地library发布到Apache Maven仓库。例如:将*.aar、*.jar等library发布到仓库当中,我们可以通过gradle或者maven进行远程依赖使用它。 二、引入插件 在需要用到的模块的build.gradle文件加入如下代码即可。 apply plugin: 'maven-publish' 三、插件使用 引入插件后,我们可以扩展一些我们自定义的属性以及任务。引入插件的模块中,我们可以通过复写p