Android - 利用 jitpack 免费发布闭源 aar

欢迎关注微信公众号:FSA全栈行动 👋

一、简述

目前(Android/java) library 的主要发布仓库有 MavenCentraljitpack,我之前也对这两种仓库的发布流程做了详细介绍:

但是,以上两种仓库,一般是用来免费发布开源 library 的,在提交库信息时,就会要求填写开源仓库的 url,如果我们不想开源源代码,仅仅只是希望把混淆后的 aar/jar 发布出去,那么上述两篇文章的流程就行不通了。

一般来说,这些平台也会提供付费服务,支持发布闭源的 library,就比如 jitpack 付费之后,才可以导入私有的 GitHub 仓库(即 private repo),从而构建并发布闭源的 library,可这笔费用不低的,具体费用见官网说明:

那有没有办法做到,既能免费又能闭源地发布 library 呢?Yes,这就是本篇要讲述的主要内容,灰常实用。

二、创建 library

温馨提示:这里只是举个简单的例子,熟悉 Android library 的朋友可以直接跳到下一节。

不管是 jar 还是 aar,对于 Android 开发者来说,都是 library,只是它们的 module 类型不同而已,简单来说,aar 是可以包含资源文件的 jar,功能更加强大,这里以 aar 为例,创建一个 android library module:

为了新手容易理解,这里有几点简单说明一下:

  1. com.android.library:是 android library module 使用的 Gradle 插件,android {} 是该插件的配置项,最终产出的库文件是 *.aar
  2. minifyEnabled:是否开启混淆,默认为 false。
  3. proguard-rules.pro:当前 library 编译时的混淆规则(minifyEnabledtrue 时生效),对生成最终的 aar 文件有影响。
  4. consumer-rules.pro:携带在 aar 文件中的混淆规则,对 别人工程 编译时的混淆规则有影响。

注:java library module 使用的 Gradle 插件是 java-libraryapply plugin: 'java-library'),没有 android{} 配置项,如需混淆,则需要依赖其他 Gradle 插件,有需要的可以看我之前写的另一篇文章。

Android - 混淆 java-library 工程:juejin.cn/post/717444...

gradle 复制代码
// build.gradle
apply plugin: 'com.android.library'

android {
    ...

    defaultConfig {
        ...
        versionCode 1
        versionName "1.0"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled true // 开启混淆
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'com.luffykou:android-common-utils:1.1.3'
}

这里我创建的 library 功能非常简单,可以将一个图片 Bitmap 转成 Base64 字符串:

java 复制代码
/**
 * GitLqr 工具类
 *
 * @author LQR
 * @since 2024/6/22
 */
public class GitLqrUtil {

    /**
     * bitmap 转 base64
     */
    public static String bitmapToBase64(Bitmap bitmap) {
        return Base64.encodeToString(bitmapToByte(bitmap), Base64.DEFAULT);
    }

    /**
     * bitmap 转 byte[]
     */
    public static byte[] bitmapToByte(Bitmap bitmap) {
        ByteArrayOutputStream o = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, o);
        return o.toByteArray();
    }
}

现在就可以编译 library 生成 aar 文件了,找到在 AS 右侧的 Gradle 面板,点开后找到 library 下的 assembleXXX task,这里我需要生成混淆后的 aar 文件,所以执行 assembleRelease,最终产物在 module 的 build/outputs/aar 目录下:

三、发布本地 maven

因为 aar 文件中只包含当前 library 的代码和资源,其依赖的第三方库不会被合并进去,想要被其他工程正常集成使用,就需要将第三方库的依赖信息传递下去,所以,需要借助 maven 发布插件,生成 pom 文件,因为 maven 插件已经过时,这里我使用的是 maven-publish 插件,library 脚本配置如下:

gradle 复制代码
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'

def LIB_VERSION_CODE = 1
def LIB_VERSION_NAME = "1.0"
def LIB_GROUP_ID = 'com.gitlqr'
def LIB_ARTIFACT_ID = 'closed_source_arr'

android {
    ...
    defaultConfig {
        ...
        versionCode LIB_VERSION_CODE
        versionName LIB_VERSION_NAME
    }
}

// 将当前module打包发布到本地maven仓库
afterEvaluate {
    publishing {
        // 配置maven 仓库
        repositories {
            // build/outputs/maven_repo
            maven { url uri(new File(buildDir, "outputs/maven_repo").path) }
        }
        // 配置发布产物
        publications {
            maven(MavenPublication) { // 容器可配置的信息 MavenPublication
                groupId LIB_GROUP_ID
                artifactId LIB_ARTIFACT_ID
                version LIB_VERSION_NAME

                // 注:AGP 3.6.0 及以上才能使用,作用是将 Android Gradle 插件生成的组件,作为发布的内容
                from components.release
            }
        }
    }
}

如果 library 使用的 AGP 版本低于 3.6.0,maven-publish 的配置会比较麻烦,具体脚本配置如下:

gradle 复制代码
task sourceJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier "sources"
}

// 将当前module打包发布到本地maven仓库
afterEvaluate {
    publishing {
        // 配置maven 仓库
        repositories {
            // build/outputs/maven_repo
            maven { url uri(new File(buildDir, "outputs/maven_repo").path) }
        }
        // 配置发布产物
        publications {
            maven(MavenPublication) { // 容器可配置的信息 MavenPublication
                groupId LIB_GROUP_ID
                artifactId LIB_ARTIFACT_ID
                version LIB_VERSION_NAME

                // 配置上传源码
                artifact(sourceJar)
                // 指定生成的aar路径
                artifact "$buildDir/outputs/aar/${project.name}-release.aar"
                // pom文件中声明依赖,从而传递到使用方
                pom.withXml {
                    def dependenciesNode = asNode().appendNode('dependencies')
                    // 必要的传递性依赖
                    def coreDependencies = ['api', 'implementation']
                    coreDependencies.each { dependency ->
                        def config = configurations[dependency]
                        println("lqr configurations = ${config}, class = ${config.class}")
                        // 提取每种传递性依赖配置中,依赖的第三方库信息
                        config.allDependencies.each {
                            def dependencyNode = dependenciesNode.appendNode('dependency')
                            dependencyNode.appendNode('groupId', it.group)
                            dependencyNode.appendNode('artifactId', it.name)
                            dependencyNode.appendNode('version', it.version)
                            // dependencyNode.appendNode('scope', dependency)
                        }
                    }
                }
            }
        }
    }
}

配置完成 maven 插件后,Gradle 面板会多出来 publishing 任务组,双击 publish 任务,即可在指定的本地目录下,生成 maven 相关的文件,其中 pom 文件非常重要,可以看到它的 <dependencies> 节点下,声明了 library 依赖的所有第三方库信息:

四、发布 jitpack

好了,现在 aarpom 文件都有了,接下来就可以着手发布到 jitpack 了。

温馨提示:当前 pom 文件非最终版本,下面的步骤,不要边看边操作,一定等完整看完之后再做操作哦~

1、创建仓库

首先,需要创建一个空白的 GitHub 仓库(名字随便),然后把 aarpom 文件上传上去:

注:pom.xml 就是上面使用 maven 插件生成出来的 closed_source_arr-1.0.pom 文件,我把它名字改了而已。

可以看到,仓库中我多上传了一个 jitpack.yml 文件,这个文件的作用是,让 jitpack 直接使用我们提供的 aarpom 文件,不需要它来生成,具体内容如下:

yml 复制代码
install:
  - FILE="-Dfile=closed_source_arr-1.0.aar"
  - mvn install:install-file $FILE -DgroupId=com.gitlqr -DartifactId=closed_source_arr -Dversion=1.0 -Dpackaging=aar -DpomFile=pom.xml

注:jitpack.yml 文件中的参数(filegroupIdartifactIdversion)根据你的库来修改,不能照抄的!参数名很好理解,相信修改起来没有任何难度。

2、创建 release

给刚刚提交的记录打个 tag,并且基于这个 tag 发布一个 release

注:因为 jitpack 会以 release 的名字作为版本号,所以,建议最好跟 aar 的版本号一致。

3、构建版本

来到 jitpack.io/,将 GitHub 仓库链接拷贝到输入框,点击 Look up 按钮:

可以看到,刚刚打的 release 被识别到了,但是此时 Log 那一列下面没有日志图标,说明 jitpack 还没有对它进行构建,点一下 Get it 按钮,再 Look up 一下就触发构建了:

注:就算不点 Get it 按钮,jitpack 也会自动触发构建的,但不知道会延迟多久,反正你想马上构建的话,就点一下吧。

因为我们已经提供了 aarpom 文件,所以 jitpack 构建会很快,1 分钟左右就出来了,但是这次日志图标是红色的,后面是 Report 按钮,说明构建失败了:

注:Status 下方按钮后面有个 × 图标,如果你自己操作的时候没有看到的话,请确认是否有登录 jitpack 账号。

点击日志图标,可以查看日志信息:

看到可以到报错信息是 ERROR: No build artifacts found,这个报错是因为我们上传的 aarpom 文件没有存放到 $HOME/.m2/repository 等标准目录下,所以 jitpack 找不到了。不过,可以给 pom 文件中声明构建时使用 android-maven-plugin 插件来解决:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
  ...
  <packaging>aar</packaging>
  <build>
    <plugins>
      <plugin>
        <groupId>com.simpligility.maven.plugins</groupId>
        <artifactId>android-maven-plugin</artifactId>
        <version>4.1.0</version>
        <extensions>true</extensions>
        <configuration>
          <encoding>utf8</encoding>
          <source>1.8</source>
          <target>1.8</target>
          <sign>
            <debug>false</debug>
          </sign>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    ...
  </dependencies>
</project>

pom.xml 修改好之后,提交到 GitHub 仓库,然后,执行以下两个步骤:

  1. 把前面创建的 releasetag 都删掉,重新走第二步,即重新打 tagrelease
  2. jitpack 页面,点击 Status 下方按钮后面的 × 图标,将构建失败的记录删除,重新走第三步,即重新触发构建。

这次日志图标是绿色的,说明构造成功了:

五、集成闭源 library

点击 Get it 按钮后,页面会向下滚动,按照 jitpack 的集成步骤,操作即可:

gradle 复制代码
// root build.gradle
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

// app build.gradle
dependencies {
    ...
    // implementation project(":library")
    implementation 'com.github.GitLqr:lib-closed-source-arr:1.0'
}

工程 rebuild 之后,能正常跑,查看 GitLqrUtil 类的引用,确实来自闭源 aar

至此,闭源的 aar 就发布成功咯,如果你觉得文章对你有帮助的话,请不吝点个免费的赞~

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~

相关推荐
whysqwhw1 小时前
安卓图片性能优化技巧
android
风往哪边走1 小时前
自定义底部筛选弹框
android
mit6.8242 小时前
[Git] 如何拉取 GitHub 仓库的特定子目录
git·github
用户466537015052 小时前
如何在 IntelliJ IDEA 中可视化压缩提交到生产分支
后端·github
Yyyy4822 小时前
MyCAT基础概念
android
用户466537015052 小时前
git代码压缩合并
后端·github
Android轮子哥2 小时前
尝试解决 Android 适配最后一公里
android
若水晴空初如梦3 小时前
QT聊天项目DAY19
github
雨白3 小时前
OkHttp 源码解析:enqueue 非同步流程与 Dispatcher 调度
android
风往哪边走4 小时前
自定义仿日历组件弹框
android