受保护的字段对子类不可见。

15
我正在编写一个自定义视图,直接扩展了android.view.View。如果我试图访问字段mScrollXmScrollY,则会出现错误,指出该字段“无法解析或不是字段”。android.view.View的源代码声明了mScrollX、mScrollY和类似的变量为protected。那么,我的直接子类为什么不能访问其父类的受保护字段?(像ScrollView这样的类显然可以。)
P.S. 我知道我可以调用getScrollX(),但我想更新这些字段;调用setScroll()会产生一些我不想要的副作用。

奇怪的是,子类即使在其他包中也可以访问其超类的受保护变量。我猜想你可能使用了错误的版本。你能展示一些代码吗? - Johan Sjöberg
3个回答

21

这是因为它们不是Android SDK的一部分。

这是mScrollX的源代码:

/**
 * The offset, in pixels, by which the content of this view is scrolled
 * horizontally.
 * {@hide}
 */
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;
你会注意到@hide注解。这意味着它不是Android SDK的一部分。构建Android SDK的过程将不会在你正在编译的android.jar文件中包含此数据成员的存根版本的android.view.View@hide注解用于需要公开或保护的内部事务,但不被视为SDK开发人员应使用的内容。
请找到其他解决方案来解决你遇到的问题。

9
嗯,很有趣!那么换句话说,理由是:“我们懒得解决适当的封装问题,所以我们破坏了语言。” - Oliver Charlesworth
我注意到了{@hide}标签。我认为这就是mScrollX没有出现在JavaDocs中的原因(就像建议的@exclude标签一样,它替代了@hide)。我没有意识到SDK只是API的存根版本。 - Ted Hopp
有一件事我不太理解,就是在 ScrollView 类中访问了 View 类的受保护变量。这怎么可能呢?类的继承关系是这样的:ScrollView 继承自 FramLayout,FramLayout 又继承自 ViewGroup,而 ViewGroup 才继承自 View。因此,View 类的受保护变量应该只被 ViewGroup 访问。 - Mitul Varmora

5
很明显:注意这些变量上方的@hide注释。这是Android特有的注释,将字段/方法从公共SDK中隐藏。这就是为什么您无法直接访问它们的原因。 Romain Guy在这篇文章中提到了它。

这很令人不安。开源的意义是什么?为了让人们能够阅读源代码并理解正在发生的事情。但是这里发布的源码是假的?不是在生产中使用的那个?如果它是透明的,那也是可以接受的。我不在乎 JDK 源代码是真实的,但是我从中获得的任何信息在真实系统中必须是正确的。 - irreputable
你必须理解开源的含义。首先,你可以直接从源代码构建自己的Android版本,对其进行任何修改,并使用所有方法或字段,无论它们是否隐藏。这就是手机制造商和社区中一些自定义ROM烹饪者所做的事情。开发人员可以从Android开源的另一个方面受益,那就是通过源代码了解幕后的工作原理,对我来说,这与文档本身同样重要。 - Lior
2
某些字段或方法被隐藏的原因通常有以下两种情况:1. 它们可能在 SDK 的未来版本中发生更改,因此他们希望降低应用程序不兼容的风险,从而为您作为开发者节省大量维护应用程序的工作。2. 直接使用这些字段(如您的情况)可能会干扰 API 内部的正常工作。 - Lior

4
您可以尝试使用反射来设置字段:

import java.lang.reflect.Field;

// ...

try {
    Field scrollXField = View.class.getDeclaredField("mScrollX");
    scrollXField.setAccessible(true);
    scrollXField.set(this, myNewValue);
} catch (Exception ex) {
    // oops, android changed the implementation. sucks to be you.
}

需要注意的是,当您进行此操作时,您正在依赖未记录和不支持的行为,因此您应该准备好在某些设备或将来的版本上出现故障。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接