上文总结了三种多模块开发的方法。
api Project(':...')
,直接引用 。我的第一个开源项目就依次用过这三种方式:
这是一个词典应用,名为“无限词典”,从2019年开源至今,现在编译起来应该很容易了:https://github.com/KnIfER/PlainDictionaryAPP
在最外层的build.gradle添加 jitpack 作为maven仓库,建议排序排在最后面。
buildscript {
repositories {
mavenLocal()
maven { url 'https://jitpack.io' }
……
}
allprojects {
repositories {
mavenLocal()
maven { url 'https://jitpack.io' }
……
}
依赖引用方法见官方主页,支持gitee:https://jitpack.io/
settings.gralde
中,勿包含与主模块同名的项目名称,如:rootProject.name = "Paging"
include ':Paging'
include ':Logger'
settings.gralde
文件用于指示gradle项目包含哪些模块文件夹(即使用第一种分模块方式),
其中 rootProject.name
可能会导致jitpack编译器报错:
* What went wrong:
A problem occurred evaluating project ':Logger'.
> Failed to apply plugin 'com.android.internal.library'.
> Your project contains 2 or more modules with the same identification com.github.appxmod:Paging
at ":" and ":Paging".
You must use different identification (either name or group) for each modules.
一些调用本地指令的gradle脚本不能用。比如我在“为Android Studio制作提示音,用音乐舒缓压力”一文中记录的提示音脚本就不能使用了。
版本管理很麻烦,所以建议所有版本号都使用最新版本(:latest.release),如
api('com.github.appxmod:Metaline:latest.release')
- 依赖引用方式变为
com.github.用户名.主项目名称:子模块名称:版本号
,而不是原来的com.github.用户名:项目名称:版本号
(参考jitpack.io的编译日志),如appxmod/GlideModule
项目中同时包含四个模块,引用起来是这个样子的:api('com.github.appxmod.GlideModule:GlideModule:latest.release') api('com.github.appxmod.GlideModule:GifDecoder:latest.release') api('com.github.appxmod.GlideModule:DiskLruCache:latest.release') compileOnly ('com.github.appxmod.GlideModule:Compiler:latest.release') annotationProcessor ('com.github.appxmod.GlideModule:Compiler:latest.release') implementation('com.github.appxmod.GlideModule:Annotation:latest.release')
- 模块之间相引用,应直接使用 project 指令,如:
api project(':模块名称')
,而不是api 'com.github……'
jitpack支持github或gitee的组织,和用户名一样,如 com.gitee.组织名称
。
maven-publish 插件会影响 jitpack 编译。比如使用 from components.all
指令,就会生成 release、debug多种编译版本,可能会导致引用出错,比如gradle根据引用项目去 jitpack.io 服务器寻找 “某组件-release.aar”,但是没有这个文件,因为对方使用的是 from components.release
,只有一个编译版本,只有 “某组件.aar”,没有 “某组件-release.aar”(参考编译日志)。
jitpack.io 的仓库可直接在浏览器中访问。
jitpack 一般是去编译 release tag,需在浏览器中访问,查看编译状态。编译速度很慢,似要排队。建议先通过本地编译,再去浏览器触发 jitpack 编译。编译必须有先后顺序,依赖项少的先来。如果编译失败,不一定要新建 release tag,可在 github 或 gitee 删除 release、tag,然后重建同名release,最后在 jitpack 页面上点“叉”图标,重新触发编译。
上面的log图标,点进去查看编译日志,绿色代表编译成功,可以正常使用了。
初次大量使用 jitpack,如有错误请指正。
jitpack上面的内容不是自己编译后上传的,而是远程机器编译。如果是独自研发,或者是原创者,那最好能够切换回本地仓库,自己去编译。
本地编译时,为每个组件加载额外的 gradle 属性文件,覆盖原有属性。
// Load keystore
def localMavenFile = rootProject.file("localMaven.properties");
if (localMavenFile.exists()) {
def props = new Properties();
props.load(new FileInputStream(localMavenFile ))
props.each { prop ->
project.ext.set(prop.key, prop.value) // 覆盖
}
}
默认的项目属性文件 gradle.properties :
libs_lucene=com.github.appxmod:Lucene:latest.release
用于覆盖重写依赖项的属性文件 localMaven.properties :
libs_lucene=org.appxmod.lucene:Core:latest.release
最后使用:
dependencies {
api libs_lucene
}
// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreDefined = keystorePropertiesFile.exists();
if (keystoreDefined) {
def props = new Properties();
props.load(new FileInputStream(keystorePropertiesFile))
props.each { prop ->
project.ext.set(prop.key, prop.value) // 直接加载到项目属性,方法来自 https://stackoverflow.com/questions/11749384/gradle-include-properties-file#answer-33484783
}
}
项目根目录新建文件keystore.properties
存储密码:
keys_storePassword=密码1
keys_keyPassword=密码2
keys_keyAlias=键名
keys_storeFile=C:\\文件路径.jks
注意没有 keys_ 前缀,会与默认的项目属性冲突
最后再在 gradle 中使用:
android { ……
//签名设置
signingConfigs {
debug {
if (keystoreDefined) {
storeFile file(keys_storeFile)
storePassword keys_storePassword
keyAlias keys_keyAlias
keyPassword keys_keyPassword
}
}
}
从TTS 、 legado等开源项目中学来的,不过有改进:1. 无需将密码存储在 gradle 中。 2. 无需加载到 keystoreProperties 对象,直接将密码等常量加载为全局属性。
多次编译竟然会报错:This feature requires ASM7
,rebuild,成功,接着修改一处字符串反复测试编译,一两三次增量编译,成功,然后再增量编译就会出现令人费解的 ASM7 问题。
毕竟是奇迹产品,一个小公司制作的世界级开发工具,虽然才华横溢,但出现种种问题也是情理之中。我常常在想,如果没有kotlin分心,如果那些上游开发者集中精力,我是否能使用更好的android studio?
报错模块是 glide 魔改组件:
error processing C:\Users\TEST\.m2\repository\org\appxmod\glide\Compiler\1.0.0\Compiler-1.0.0.jar
java.lang.UnsupportedOperationException: This feature requires ASM7
at org.objectweb.asm.ClassVisitor.visitNestHost(ClassVisitor.java:150)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:541)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:153)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyzeJar(DesugaringClassAnalyzer.java:100)
at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:68)
at com.android.build.gradle.internal.tasks.DesugarIncrementalHelper.lambda$getInitalGraphData$4(DesugarIncrementalHelper.java:146)
at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1448)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
最后发现是连续用 build > make project 菜单构建项目就会报错,也不知道什么原因,反正是直接运行反而不会报错,不用修复。这个问题以前遇到过,没写笔记记住。
无限词典打包release前需要编译一下某些js或html内容,需要打包一些资源文件。
算了。太难实现了,谁会?
还是用单独运行IDEA吧。