我今天在我們的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