我今天在我们的Android代码库中发现了这个问题,让我的同事感到困惑。我们以前有一类结构如下所示:在不同版本的Android中受保护的内部类可见性差异
Foo.java
package test.a;
public abstract class Foo extends View {
protected abstract class InnerFoo {
public InnerFoo() {}
}
protected class Cog {
public Cog() {}
}
}
Bar.java
package test.a;
public class Bar extends Foo {
private abstract class AbstractInnerBar extends InnerFoo {
protected abstract void someMethod();
}
private class InnerBar extends AbstractInnerBar {
Cog myCog;
public InnerBar() {
myCog = new Cog();
}
protected void someMethod() {}
}
}
我明白这个类的结构不一定简单,但它的工作没有问题。不过,我们最近做了一些包重组,并意识到Bar在别的地方。所以,我们把它移到了不同的包里,几乎有相同的结构,有两个不同的包。
Foo.java
package test.a;
public abstract class Foo extends View {
protected abstract class InnerFoo {
public InnerFoo() {}
}
protected class Cog {
public Cog() {}
}
}
Bar.java
package test.b; //This is the only change
public class Bar extends Foo {
private abstract class AbstractInnerBar extends InnerFoo {
protected abstract void someMethod();
}
private class InnerBar extends AbstractInnerBar {
Cog myCog;
public InnerBar() {
myCog = new Cog();
}
protected void someMethod() {}
}
}
奇怪的是,在变更后的一些 Android版本,我们得到这样的错误:java.lang.IllegalAccessError: tried to access class test.a.Foo$Cog[] from class test.b.Bar$InnerBar
。我不认为这会是一个问题,因为Cog
给出protected
知名度,Bar extends Foo
和InnerBar
延伸InnerFoo
。奇怪的是,其他版本的Android工作正常(没有错误,没有可见性问题)。我们能够通过宣布Cog
为public
来解决问题,但这似乎是一种不必要的解决方法。
我们在运行Android 4.4.4的摩托罗拉Moto X(第一代开发版)上看到了这个问题。我们在运行Android 4.1.2的Nexus 5上运行Lollipop或Nexus S时没有问题。谁能说明这一点?
如果您在部署APK之前清理项目,还会出现错误吗? – 2014-12-11 03:00:23
干净后仍然会出现错误。我甚至有一位同事在他的机器上制作一个APK,在他的手机上运行(Nexus 5/Lollipop),然后adb在Moto X/KK上安装相同的APK,并且它崩溃。 – loopyzort 2014-12-11 20:18:18