构建你的私有仓库,发布你的库,提高工程构建速度

688 阅读4分钟

前言

gradle是一个自动化构建工具,它会自动从远程服务上下载你配置的依赖,比如

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

简单的一句就可也在项目中使用 okhttp3.10.0 了,是不是很方便?但是具体是如何做到的呢?

原理

首先gradle会去本地查是否已经下载,目录为:
如果下载了则直接使用,未下载则开始下载,下载的源头工程默认是:

   repositories {
        google()
        jcenter()
    }

即Google()

    public MavenArtifactRepository google() {
        return addRepository(repositoryFactory.createGoogleRepository(), GOOGLE_REPO_NAME);
    }
    
    public MavenArtifactRepository createGoogleRepository() {
        MavenArtifactRepository mavenRepository = createMavenRepository(new NamedMavenRepositoryDescriber(RepositoryHandler.GOOGLE_URL));
        mavenRepository.setUrl(RepositoryHandler.GOOGLE_URL);
        return mavenRepository;
    }
    
    String GOOGLE_URL = "https://dl.google.com/dl/android/maven2/"

jcenter()

    public MavenArtifactRepository jcenter() {
        return addRepository(repositoryFactory.createJCenterRepository(), DEFAULT_BINTRAY_JCENTER_REPO_NAME);
    }
    public MavenArtifactRepository createJCenterRepository() {
        MavenArtifactRepository mavenRepository = createMavenRepository(new NamedMavenRepositoryDescriber(DefaultRepositoryHandler.BINTRAY_JCENTER_URL));
        mavenRepository.setUrl(DefaultRepositoryHandler.BINTRAY_JCENTER_URL);
        return mavenRepository;
    }
	String BINTRAY_JCENTER_URL = "https://jcenter.bintray.com/"

仓库:

dl.google.com/dl/android/…
jcenter.bintray.com/

最终在上述两个仓库进行下载资源,很显然因为国内墙的原因,速度不理想或干脆访问不了。

引入国内仓库

为了解决,国内自建了很多同步仓库,供国人使用,例如阿里云

https://maven.aliyun.com/repository/google //Google公司提供的仓库google
https://maven.aliyun.com/repository/jcenter //JFrog公司提供的Jcenter
https://maven.aliyun.com/repository/central //Sonatype公司提供的central
https://maven.aliyun.com/nexus/content/repositories/central //Sonatype公司提供的central
https://maven.aliyun.com/repository/google //Google公司提供的仓库google
https://maven.aliyun.com/nexus/content/repositories/google //Google公司提供的仓库google
https://jitpack.io //JitPack提供的仓库
https://maven.aliyun.com/nexus/content/groups/public //jcenter和mavenCentral的聚合仓库
https://maven.aliyun.com/repository/public //jcenter和mavenCentral的聚合仓库
https://maven.aliyun.com/repository/gradle-plugin  //Gradle插件仓库
https://maven.aliyun.com/nexus/content/repositories/gradle-plugin //Gradle插件仓库

我们可以把依赖仓库改成上述仓库,基本就能解决所有开源库下载问题,例如在根目录build.gradle下加入上述仓库

buildscript {
repositories {
 	//加入多个仓库地址
        maven{url uri('https://maven.aliyun.com/repository/google') }
        google()
        jcenter()
    }
}
allprojects {
    repositories {
      //加入多个仓库地址
        maven{url uri('https://maven.aliyun.com/repository/google') }
       
         google()
        jcenter()
    }
}

引入私有库

这样虽然能解决,但是为什么还要自己搭建呢,目前我的原因是这三点:
1、共享公司内部开发的模块,方便内部依赖在内网分发,同时避免内部代码传到外网
2、由于众所周知的原因,下载国外服务器上的依赖很慢,通过内网将相关文件缓存一方面加快了依赖安装的速度也减轻了出口带宽压力
3、不需要在加入多个仓库地址,加入一个自建的私有代理仓库即可

我选择使用artifactory 搭建 maven 仓库。至于我为什么选择了 artifacory,是因为artifactorygradleandroid 支持的更顺畅,界面也更好看更现代化一点。当然你也可以选择老牌的 nexus

安装Artifactory

如何安装artifactory, 这里有一篇完整的教程,我windows、mac系统都验证过,跟着步骤来就行,不做过多说明,也附带pro版本哦。

安装完artifactory、配置好本地仓库、远程仓库,然后引入虚拟仓库包裹这两者,而gradle文件中则只需要引入虚拟仓库即可,无需再添加多个配置 至此配置完毕,重新构建,第一次构建,你会发现artifactory在不断增加,直到停止,你的工程构建也完毕。下次或者其他人在构建时则变的很快

同步给你的小伙伴,让他引入你的私有仓库。在局域网环境下又不是初次载入,自然特别快,对刚入职的小伙伴或者加入新项目而言是有很好的帮助。

发布库文件到Artifactory私有仓库

解决了2、3两个问题后,自然而然面临着如何发布库到仓库中。 解决方法很简单,这里提供了示例做法,详情可以参考 - ArtifactoryExample

例如在AndroidStudio的Module-library工程中的build.gradle加入publishing、artifactoryPublish节点

apply plugin: 'com.android.library'
apply plugin: 'maven-publish' //必须加入这个插件
apply plugin: 'com.jfrog.artifactory' //必须加入这个插件
android {
		......
}

publishing {
    publications {
        aar_publish(MavenPublication) {//注意这里定义的 aar_publish,在artifactoryPublish 下需要使用
            groupId = rootProject.ext.maven.groupId //公司
            artifactId = rootProject.ext.maven.artifactId //项目
            version = rootProject.ext.maven.version //版本

            // aar文件所在的位置
            // module打包后所在路径为module模块下的build/outputs/aar,生成的aar名称为:module名-release.aar
            artifact("$buildDir/outputs/aar/" + getReleaseName()) 
        }
    }
}
//每次上传必须clean
artifactoryPublish {
    contextUrl = rootProject.ext.maven.local
    publications('aar_publish')        //注意这里使用的是上面定义的 aar_publish

    clientConfig.publisher.repoKey = rootProject.ext.maven.repoKey        //上传到的仓库地址
    clientConfig.publisher.username = rootProject.ext.maven.username        //artifactory 登录的用户名
    clientConfig.publisher.password = rootProject.ext.maven.password    //artifactory 登录的密码
}

需要注意的是,每次发布前需要clean一下当前工程,否则会出现未上传的情况。
具体步骤为执行cleanassemble生成了aar文件后,点击publish - > artifactoryPublish,发布到私有仓库,根据你发布的repoKey检查是否上传成功

引入你发布的私有库

发布完私有库后,告知你团队的小伙伴私有库的地址,构成为 $groupId:$artifactId:$version,例如在你app工程引用该aar,app目录下build.gradle

plugins {
    id 'com.android.application'
}
android {
	....
}
dependencies {
	implementation "'com.squareup.okhttp3:okhttp:3.10.0"//groupId = com.squareup.okhttp3 , artifactId = okhttp , version = 3.10.0"
}

至此解决了问题1,让你的小伙伴都赶快使用起来吧。