2011-02-06 2 views
15

android.view.View으로 직접 확장되는 사용자 정의보기를 작성하고 있습니다. mScrollX 또는 mScrollY 필드에 액세스하려고하면 "해결할 수 없거나 필드가 아닙니다."라는 오류 메시지가 나타납니다. source code for android.view.View에는 mScrollX, mScrollY 및 유사한 변수가 protected으로 선언되어 있습니다. 직접 하위 클래스가 상위 클래스의 보호 된 필드에 액세스 할 수없는 이유는 무엇입니까? (ScrollView과 같은 클래스가 가능합니다.)보호 된 필드가 하위 클래스에 표시되지 않습니다.

P.S. 내가 getScrollX()라고 부를 수 있다는 것을 알았지 만이 필드를 업데이트하고 싶습니다. setScroll()에는 부작용이 있습니다. 원하지 않는 부작용이 있습니다.

+0

이상한 하위 클래스는 다른 패키지에 있어도 수퍼 클래스의 보호 된 변수에 액세스 할 수 있습니다. 나는 당신이 틀린 버전을 사용하고 있다고 생각합니다. 코드 일부를 보여줄 수 있습니까? –

+0

동작이 확인되었습니다. –

답변

20

Android SDK의 일부가 아니기 때문입니다.

/** 
* The offset, in pixels, by which the content of this view is scrolled 
* horizontally. 
* {@hide} 
*/ 
@ViewDebug.ExportedProperty(category = "scrolling") 
protected int mScrollX; 

당신은 @hide 주석을 알 수 있습니다 : 여기

mScrollX의 소스 코드입니다. 즉, Android SDK의 일부가 아닙니다. Android SDK를 만드는 빌드 프로세스의 일부는 컴파일 할 android.jar 파일에있는 android.view.View의 스텁 버전에이 데이터 멤버를 포함하지 않습니다.

@hide 주석은 내부 목적으로 공개되거나 보호되어야하지만 SDK 개발자가 사용해야하는 것으로 간주되지 않는 것에 사용됩니다.

발생하는 모든 문제에 대한 다른 해결책을 찾으십시오.

+9

흠, 재미 있습니다! "우리는 적절한 캡슐화를 분류하는 데 신경 쓰지 않아서 언어를 전복했다."... –

+0

나는 {{@hide} 태그를 발견했다. 필자는'mScrollX'가 (제안 된'@ exclude' 태그 (http://java.sun.com/j2se/javadoc/proposed-tags.html)와 같이) JavaDocs에 나타나지 않았고, @ 숨기기 '). SDK가 스텁 버전의 API라는 것을 알지 못했습니다. –

+0

내가 이해할 수없는 한 가지는 ** View ** 클래스의 Protected 변수가 ** ScrollView ** 클래스에서 액세스된다는 것입니다. 이것이 어떻게 가능한지 ? 계층 구조 - ScrollView extends FramLayout extends ViewGroup extends View. View 클래스의 protected 변수는 ViewGroup에서만 액세스 할 수 있어야합니다. –

5

매우 간단합니다. 이러한 변수 위에 @hide 주석이 있는지 확인하십시오. 공개 SDK에서 필드/메소드를 숨기는 Android 관련 특수 효과입니다. 그래서 직접 액세스 할 수 없습니다.

Romain Guy mentioned it in이 게시물.

+0

이 방해가됩니다. 오픈 소스의 핵심은 무엇입니까? 사람들은 소스를 읽고 무슨 일이 벌어지고 있는지 이해할 수 있습니다. 하지만 여기에서 나온 자료는 가짜 것입니까? 생산에 사용 된 것이 아닌가? 또한 허용되는 * 투명하면 *.JDK 소스가 * 진짜 * 하나인지는 상관하지 않지만, 읽은 정보는 실제 시스템에서 true 여야합니다. – irreputable

+0

오픈 소스의 의미를 이해해야합니다. 우선 소스에서 직접 Android 버전을 빌드하고 원하는대로 수정하고 모든 메소드 또는 필드를 숨김 여부와 상관없이 사용할 수 있습니다. 그것이 전화 제조업체가하는 일이며 지역 사회의 맞춤 ROM 요리사들 중 일부입니다. 개발자는 안드로이드가 오픈 소스라는 또 다른 측면에서 이익을 얻을 수 있습니다. 이것은 소스를 통해 진행되며 상황이 어떻게 작동 하는지를 이해합니다. 이는 문서 자체만큼 중요합니다. – 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. 
} 

단, 그래서 당신은 휴식하는 것들에 대한 준비를해야합니다 일부 기기 또는 이후 버전에서

관련 문제