Android—Gradle教程(六)

前言

在前几篇文章中,已经讲AGP相关配置讲解完毕。从这一篇开始将会开启AGP实战相关的内容。

本篇实战内容:

  1. AGP实战一:启用multiDex打包
  2. AGP实战二:aar打包发布maven

1. AGP实战一:启用multiDex打包

我们编写代码难免会导入三方资源库,几个版本过后阔能就会出现65535方法数限制这个错误。因为DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。这个链表的长度是用short类型来保存的,这就使得方法数id不能超过65535。

所以说一个dex文件是不能超过65535个方法数量,通过打包多个dex文件来解决问题。

我们先来看看正常情况未使用multiDex打包的APK结构:

在这里插入图片描述
如图所示

这里有且仅有一个dex包,当方法数如果超过65535的时候,打包时就会报错。为了避免报65535这个错,下面就开始如何避免该问题。

android {
    
    
    compileSdkVersion 30

    defaultConfig {
    
    
        applicationId "com.hqk.gradledemo05"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        // DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。
        // 这个链表的长度是用short类型来保存的,这就使得方法数id不能超过65535。
        // 一个dex方法数不能超出65535.
        // 1.设置multiDexEnabled true
        // 2.创建MyApplication 继承MultiDexApplication
        // 3.AndroidManifest指定MyApplication
        // 4.或者重写attachBaseContext 调用MultiDex.install(this)
        multiDexEnabled true

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

}

这里将multiDexEnabled设置成了true,过后就要对Application进行改造

class MyApplication : /*MultiDexApplication()*/Application() {
    
    
    override fun attachBaseContext(base: Context?) {
    
    
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

这里如注释所说,有两种方式,要么直接继承MultiDexApplication ;要么继承普通Application 但要重写对应attachBaseContext方法并且执行MultiDex.install(this)代码。比如说集成Tinker热修复的时候,MyApplication 就可以用第二种方式。

现在我们重新打包编译看看效果:
在这里插入图片描述
如图所示

打包好的APK已经自动帮我们分包了。接下来开启第二个实战:

2. AGP实战二:aar打包发布maven

2.1 什么是aar?

  • aar就是Android library的二进制归档文件,包含所有资源,class以及res资源文件全部包含。简单来说就是android library工程进行单独打包后的产物
  • 将aar解压(后缀改为.zip,再解压文件)打开后,可以看到每个aar解压后的内容可能不完全一样,但是都会包含AndroidManifest.xml,classes.jar,res,R.txt

2.2 如何打包aar

  1. 先在项目工程中创建library,并且在主工程中依赖这个librar
  2. 然后在library的任务集中找到assemble这个任务
  3. 调用这个assemble任务进行对library打包,会生成对应的aar文件,存放在当前library工程的build/outputs/aar目录下

2.3 依赖aar

  • 可以把aar放入到libs文件夹下,然后通过相对路径的方式依赖进来
    • implementation files(‘libs/xxxxxx.aar’)
  • 或者通过添加respositories{flatDir{dirs ‘libs’}},然后在进行依赖
    • implementation files(name:‘xxxxxx.aar’, ext:‘aar’)
  • 还可以通过把aar发布到maven仓库,然后通过maven来管理这些远程的aar文件,具体依赖就跟使用第三方git上的这些library一样了

在这里插入图片描述
如图所示

这里将打包以及前两种引入aar的方式都在这张图标识了出来,不过这些都不是重点,直接一笔带过。我们的重点是第三个:发布到maven仓库,然后通过maven实现远程依赖。

2.4 通过maven脚本插件发布

plugins {
    
    
    id 'com.android.application'
    id 'kotlin-android'
    id 'maven'
}

android {
    
    
	...-
}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!下面AAR的文件名改成你放到libs文件夹里的文件名
def coreAarFile = file('libs/mylibrary-release.aar')
artifacts {
    
    
    archives coreAarFile
}

uploadArchives {
    
    
    repositories.mavenDeployer {
    
    
        pom.groupId = "com.hqk.library"
        pom.artifactId = "mylibrary"
        pom.version = "1.0.0"
        //pom.version = '1.0.0-SNAPSHOT'
        //自定义本地仓库
        repository(url: uri('../repostory'))
    }
}

开头引入了 maven 脚本插件,随后指定需要发布的aar,并且设置对应的信息,最后指定与本地仓库。

在这里插入图片描述
如图所示

执行右侧task,执行完毕后,左侧将会生成本地库相关的文件,此时回到项目的bulid.gradle文件

allprojects {
    
    
    repositories {
    
    
        google()
        mavenCentral()
//        jcenter() // Warning: this repository is going to shut down soon
        maven {
    
    
            //F:\AndroidProjectDemo\gradledemo05
            url 'file://F://AndroidProjectDemo//gradledemo05//repostory'
        }
    }
}

将本地maven仓库地址引入进来,接着回到项目的bulid.gradle 就可以通过implementation导入aar了:

android{
    
    
...略
	dependencies {
    
    
		...略
		
	    implementation  'com.hqk.library:mylibrary:1.0.0'
	}
}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!下面AAR的文件名改成你放到libs文件夹里的文件名
def coreAarFile = file('libs/mylibrary-release.aar')
artifacts {
    
    
    archives coreAarFile
}

uploadArchives {
    
    
    repositories.mavenDeployer {
    
    
        repository(url: uri('../repostory'))
        pom.groupId = "com.hqk.library"
        pom.artifactId = "mylibrary"
        pom.version = "1.0.0"
    }
}

编译构建成功时就能使用 mylibrary 里面的代码逻辑了。

在这里插入图片描述
完美运行!

但是!!敲黑板了!!这种方式在Gradle6过后就被废弃了。所以我们还得学习第二种方式,通过maven-publish发布到仓库。

2.5 通过maven-publish脚本插件发布

准备工作:先将原来的依赖方式清除!

项目工程的build.gradle

allprojects {
    
    
    repositories {
    
    
        google()
        mavenCentral()
//        jcenter() // Warning: this repository is going to shut down soon
        maven {
    
    
            //F:\AndroidProjectDemo\gradledemo05
//            url 'file://F://AndroidProjectDemo//gradledemo05//repostory'
            url 'file://F://AndroidProjectDemo//gradledemo05//repository03'
        }
    }
}

重新依赖了新的本地仓库,在这里文件夹不存在不要紧,可以不用手动创建。

项目build.gradle

//    implementation  'com.hqk.library:mylibrary:1.0.0'

注释掉原有的依赖!

//import com.hqk.mylibrary.TestUtil

class MainActivity : AppCompatActivity() {
    
    

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
       // TestUtil.print()
    }
}

只要关于之前依赖相关的全部注释掉。到这里就与上面那种方式没有任何关系了。可以开始写新的脚本了。

进入对应library下的build.gradle ,添加如下脚本:

plugins {
    
    
    id 'com.android.library'
    id 'kotlin-android'
    id 'maven-publish'
}

android{
    
    
...}
...略
dependencies {
    
    
...}

//上传源码对应的task
task generateSourcesJar(type: Jar) {
    
    
    from android.sourceSets.main.java.getSrcDirs() // 源码路径
    archiveClassifier= "sources"
}


def versionName = "1.1.1"

afterEvaluate{
    
    
    publishing{
    
    
        repositories {
    
    
            maven{
    
    
            	//自定义本地仓库
                url="F://AndroidProjectDemo//gradledemo05//repository03"
            }
//        // 定义一个 maven 仓库
//        maven {
    
    
//            //在这里放远程仓库地址
//            url = "https://xxxxxxxx"
//            // 仓库用户名密码
//            credentials {
    
    
//                username = "root"
//                password = "root"
//            }
//        }
        }
        publications{
    
    
            maven(MavenPublication) {
    
    
            	//这个 components 表示 library构建成功后对应的Android组件
                from components.release 
                artifact generateSourcesJar // 上传源码
                groupId =  "com.hqk.library"
                artifactId = "mylibrary"
                version = versionName
            }
        }
    }
}

注意看,这里依赖的是maven-publish插件,随后在afterEvaluate这个闭包里实现了maven-publish插件里面的publishing对应的task。发布脚本就这么点,先clear项目删除.gradle文件夹,然后在构建编译,当编译没报错时,则说明成功了一大半。

在这里插入图片描述
如图所示

点击右侧对应的publish,运行成功后,左侧将会生成对应maven的本地仓库文件夹。

此时进入项目里的bulid.gradle这次重新依赖仓库里面的aar。

//    implementation  'com.hqk.library:mylibrary:1.0.0'
    implementation  'com.hqk.library:mylibrary:1.1.1' //这次版本为 1.1.1

在对应的业务逻辑代码

import com.hqk.mylibrary.TestUtil

class MainActivity : AppCompatActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        TestUtil.print()
        TestUtil.hello()
    }
}

在这里插入图片描述
如图所示

通过鼠标也能进入查看对应aar的逻辑代码,而且还能查看对应的注释。

结束语

好了,到这里,本篇差不多结束了!相信小伙伴们对Gradle有了深一步的理解。

Guess you like

Origin blog.csdn.net/qq_30382601/article/details/121142072