Sir*_*Lam 7 dependencies android gradle android-studio android-gradle-plugin
我刚刚创建了一个库并上传到bintray和jcenter.
在我的测试应用程序中,此库作为模块添加:
implementation project(':dropdownview')
一切都井井有条.
将库模块上传到jcenter后,我改为使用它:
implementation 'com.asksira.android:dropdownview:0.9.1
然后,当库尝试调用依赖于另一个库的方法时,会发生运行时错误:
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.transitionseverywhere.TransitionSet" on path: DexPathList[[zip file "/data/app/com.asksira.dropdownviewdemo-6fj-Q2LdwKQcRAnZHd2jlw==/base.apk"],nativeLibraryDirectories=[/data/app/com.asksira.dropdownviewdemo-6fj-Q2LdwKQcRAnZHd2jlw==/lib/arm64, /system/lib64, /system/vendor/lib64]]
Run Code Online (Sandbox Code Playgroud)
(我按照本指南发布了库.我在使用相同的方法之前已经发布了3个库,它们都运行良好;但这是我第一次在我自己的库中包含另一个第三方库依赖项.)
然后我尝试更改我的库的第三方库依赖项
implementation 'com.andkulikov:transitionseverywhere:1.7.9'
至
compile 'com.andkulikov:transitionseverywhere:1.7.9'
(请注意,这不是app对我的库的依赖,而是我的库到另一个库)
然后再次上传到版本0.9.2的bintray.
implementation 'com.asksira.android:dropdownview:0.9.2
这次它工作了吗?!
这是Android Studio/Gradle的某种错误(但Google表示他们将在compile2018年底删除...),或者我做错了什么?
可在此处找到v0.9.1的完整源代码.
请注意,我并没有直接访问任何方法app来TransitionsEverywhere.具体来说,ClassNotFoundException当我点击DropDownView,并DropDownView调用expand()哪个是public内部方法时发生.
为了消除等因素的影响,以下是我已经改变之前试过的东西implementation来compile,根本没有运气:
我现在遇到了完全相同的问题,根据您的评论,我真的怀疑这是否应该是这样。我的意思是用干净的抽象替换implementation库内的所有内容是api没有意义的。如果不需要,有时甚至不应该允许使用我的库的使用依赖项,为什么我应该向消费者/应用程序公开它们。
我还检查了生成的 APK 确实包含它抱怨找不到的类。
由于我之前遇到过依赖问题,我记得我自己改进了为库生成的 POM。
在我改进之前,生成的pom是这样的:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tld.yourdomain.project</groupId>
<artifactId>library-custom</artifactId>
<version>1.2.0-SNAPSHOT</version>
<packaging>aar</packaging>
<dependencies/>
</project>
Run Code Online (Sandbox Code Playgroud)
我使用以下脚本添加依赖项,并基于implementation或api向它们添加正确的范围(基于该不错的信息)
apply plugin: 'maven-publish'
task sourceJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
archiveClassifier = "sources"
}
task listDependencies() {
// Curious, "implementation" also contains "api"...
configurations.implementation.allDependencies.each { dep -> println "Implementation: ${dep}" }
configurations.api.allDependencies.each { dep -> println "Api: ${dep}" }
}
afterEvaluate {
publishing {
publications {
mavenAar(MavenPublication) {
groupId libraryGroupId
artifactId libraryArtefactId
version versionName
artifact sourceJar
artifact bundleReleaseAar
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.api.allDependencies
.findAll { dependency -> dependency.name != "unspecified" }
.each { dependency ->
addDependency(dependenciesNode.appendNode('dependency'), dependency, "compile")
}
configurations.implementation.allDependencies
.findAll { dependency -> !configurations.api.allDependencies.contains(dependency) }
.findAll { dependency -> dependency.name != "unspecified" }
.each { dependency ->
addDependency(dependenciesNode.appendNode('dependency'), dependency, "runtime")
}
}
}
}
repositories {
maven {
def snapshot = "http://repo.yourdomainname.tld/content/repositories/snapshots/"
def release = "http://repo.yourdomainname.tld/content/repositories/releases/"
url = versionName.endsWith("-SNAPSHOT") ? snapshot : release
credentials {
username nexusUsername
password nexusPassword
}
}
}
}
}
def addDependency(dependencyNode, dependency, scope) {
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
dependencyNode.appendNode('scope', scope)
}
Run Code Online (Sandbox Code Playgroud)
您需要了解的关键部分:
implementationapi依赖项也包含这些,只需运行任务listDependencies()即可查看输出runtimeAPI 在应用程序/消费者中不可用,但属于类路径的一部分。这样,消费者就无法直接访问这些依赖项,只能通过您自己的库提供的方法使这些依赖项“不可见”,但它们将成为类路径的一部分,因此当“不可见”依赖项的这些类被访问时,应用程序不会崩溃。由类加载器加载。上面的脚本现在生成以下 pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tld.yourdomain.project</groupId>
<artifactId>library-custom</artifactId>
<version>1.2.0-SNAPSHOT</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>tld.dependency</groupId>
<artifactId>android-sdk</artifactId>
<version>1.2.3</version>
<scope>compile</scope> <!-- From api -->
</dependency>
<dependency>
<groupId>tld.dependency.another</groupId>
<artifactId>another-artifact</artifactId>
<version>1.2.3</version>
<scope>runtime</scope> <!-- From implementation -->
</dependency>
<!-- and much more -->
</dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)
把它们加起来:
api发布类,使消费者也可以访问依赖项implementation也运送类,但不会使依赖项可供使用者访问,但在定义的runtime范围内,它仍然是类路径的一部分,使类加载器知道这些类在运行时可用编辑
如果您要进行大量更改并测试快照,请确保已禁用它们的缓存。将其添加到您的根 build.gradle 文件中:
allprojects {
configurations.all() {
// to make sure SNAPSHOTS are fetched again each time
resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
// more stuff here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
944 次 |
| 最近记录: |