这是一个测试项目:
click
我有一个测试Gradle Android项目有三个模块:app,library_a,library_b.应用程序依赖于library_a,然后library_a依赖于library_b:
build.gradle(app)
dependencies {
...
compile (project(":library_a")){
transitive = false;
}
}
build.gradle(library_a)
dependencies {
...
compile (project(":library_b")){
transitive = false;
}
}
请注意,我设置transitive = false,因为我不希望从app访问library_b中的类
每个模块只有一个类,代码非常简单:
应用:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
ClassA classA = new ClassA();
classA.doSomething();
}
}
library_a:
public class ClassA
{
public void doSomething(){
Log.i("Test", "Done A!");
ClassB classB = new ClassB();
classB.doSomething();
}
}
library_b:
public class ClassB
{
public void doSomething(){
Log.i("Test", "Done B!");
}
}
好吧,问题在于:我正在用gradlew构建我的项目. Apk正在成功编译,但是当我运行它时,我得到了NoClassDefFoundError.
I/Test﹕ Done A!
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: ru.pvolan.library_b.ClassB
at ru.pvolan.somelibrary.ClassA.doSomething(ClassA.java:12)
...
如果我在两个.gradle文件中设置transitive = true,它运行正常,但是,正如我上面提到的,我不希望依赖是可传递的,只要我不希望可以从MainActivity访问ClassB – 只有ClassA .
我究竟做错了什么?
最佳答案 问题是library_b是必需的依赖项.您不能简单地排除它,因为您需要它在运行时位于类路径上.您实际上是在歪曲您的实际依赖关系,以强制执行代码约定,从而失去利用Gradle等依赖关系管理系统的任何优势.如果你想强制执行类或包黑名单,我建议使用像PMD这样的源分析工具.这是将特定类列入黑名单的
an example规则.
如果由于某种原因无法做到这一点,您可以通过简单地将library_b添加到app的运行时类路径来使上述示例“工作”.
dependencies {
runtime project(':library_b')
}