android:onClick
속성을 지정 하면 Button
인스턴스가 setOnClickListener
내부적으로 호출 됩니다. 따라서 아무런 차이가 없습니다.
명확한 이해 onClick
를 위해 프레임 워크가 XML 속성을 처리 하는 방법을 살펴 보겠습니다 .
배치 파일이 팽창되면 여기에 지정된 모든 뷰가 인스턴스화됩니다. 이 경우 Button
인스턴스는 public Button (Context context, AttributeSet attrs, int defStyle)
생성자를 사용하여 생성됩니다. XML 태그의 모든 속성은 자원 번들에서 읽고 AttributeSet
생성자 로 전달됩니다 .
Button
클래스는 생성자를 호출 View
하는 클래스 에서 상속 View
되며을 통해 클릭 콜백 핸들러를 설정합니다 setOnClickListener
.
attrs.xml에 정의 된 onClick 속성은 View.java 에서로 참조됩니다 R.styleable.View_onClick
.
다음은 그 자체 View.java
로 전화 setOnClickListener
하여 대부분의 작업을 수행 하는 코드입니다 .
case R.styleable.View_onClick:
if (context.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new OnClickListener() {
private Method mHandler;
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = getId();
String idText = id == NO_ID ? "" : " with id '"
+ getContext().getResources().getResourceEntryName(
id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ getContext().getClass() + " for onClick handler"
+ " on view " + View.this.getClass() + idText, e);
}
}
try {
mHandler.invoke(getContext(), View.this);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not execute non "
+ "public method of the activity", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Could not execute "
+ "method of the activity", e);
}
}
});
}
break;
보시다시피, setOnClickListener
코드에서와 같이 콜백을 등록하기 위해 호출됩니다. 단지 Java Reflection
우리의 활동에 정의 된 콜백 메소드를 호출하는 데 사용 한다는 점만 다릅니다 .
다른 답변에서 언급 된 문제의 이유는 다음과 같습니다.
- 콜백 방법은 공개한다 : 이후
Java Class getMethod
를 검색 지정자 공용 액세스 사용 만 기능한다. 그렇지 않으면 IllegalAccessException
예외 를 처리 할 준비가됩니다 .
- Fragment에서 onClick과 함께 Button을 사용하는 동안 콜백은 Activity에서 정의되어야합니다 .
getContext().getClass().getMethod()
call은 메소드 검색을 현재 컨텍스트 (Fragment의 경우 Activity)로 제한합니다. 따라서 메소드는 Fragment 클래스가 아닌 Activity 클래스 내에서 검색됩니다.
- 콜백 방법은보기 매개 변수를 받아 들여야한다 가입일 :
Java Class getMethod
받아들이는 방법에 대한 검색 View.class
매개 변수로합니다.