카테고리 없음

디스패치 이벤트 or 프리임 핸들러

Request 2011. 3. 10. 16:57
onDispatch Event() or onPreIme()

디스패처(Dispatcher) 이벤트 란?

 망의 전송 링크나 노드에 장애가 발생하는 것과 같은 이벤트를 탐지하여 보고하는 실체(이벤트 소스)와 그 보고를 받아서 반응하는 실체(이벤트 싱크) 간의 중간 매개 역할을 하는 기능 또는 장치.

(네이버 정의)

본론)

가상키를 이용하여 엉망으로 만들기 (Making a mess with virtual Keys)

 이제 이러한 모든 변화에 대한 본래의 동기에 관한 이야기를 시작한다: Droid 와 새롭게 출시되는 장치들에서는 가상 하드 키를 지원한다. 이러한 장치들은 물리적인 버튼 대신 터치에 민감한 구역 내에 하드 키를 위한 영역을 생성하여 시각적인 화면 밖에 확장된 터치 센서를 가지고 있다. 저수준 입력 시스템은 이 영역 내에서 스크린의 터치를 찾고 이들을 적절한 가상 하드 키로 변환한다.

 비록 생성된 이벤트에 이 이벤트를 확인하기 위한 새로운 FLAG_VIRTAL_HARD_KEY 비트가 설정되어 있지만 애플리케이션에게는 이것이 기본적으로 실제 하드키 처럼 보인다. 이 플래그에 상관없이 거의 모든 경우에 애플리케이션은 이 하드 키 이벤트를 실제 하드키를 처리했던 것과 동일한 방법으로 처리할 수 있다.

 그러나, 이 키들은 사용자 액션에 있어 약간의 문제를 야기한다. 가장 중요한 것은 사용자 인터페이스의 나머지로서 동일한 화면에 존재함으로 인해 동일한 터치로 쉽게 눌려질 수 있다는 것이다. 예를 들어, 가상 키들이 화면 하단에 위치해 있을 때 이슈가 될 수 있다: 스크롤을 위한 화면을 swipe up(화면을 손가락으로 밀어 올리는 행위)은 일반적인 제스쳐이고 이 제스처를 할 때 화면 하단의 가상 키를 우연히 건드리는 일이 매우 쉽게 발생할 수 있다.

 2.0에서는 이것에 대한 해결책으로서 취소된키 이벤트 개념을 소개한다. 긴 입력 처리가 뒤이은 이벤트를 취소한다는 것은 앞 이야기에서 이미 소개되었다. 비슷한 방법으로, 가상 키를 누른 채 화면 위를 움직이는 것은 그 키가 릴리즈 될 때 그 가상 키가 취소 되도록 할 것이다.

 사실상 이전의 코드는 이미 이것을 염두에 두고 있다 Up isCanceled() 를 체크함으로써 취소된 가상 키와 긴 입력은 무시될 것이다. 이 두 경우에 대한 개인적인 플래그가 역시 존재하지만 애플리케이션에서는 거의 사용되지 않고 키 이벤트가 취소된 것에 대한 좀 더 많은 원인이 있을 수 있다는 것에 대한 이해를 항상 가지고 있어야 한다.

 현존하는 애플리케이션의 경우, 액션이 다운 되었을 때 실행하도록 하는 BACK 키 호환성이 켜져 있다면, 손가락으로 밀기(swipe)를 수행하려고 할 때 우연히 BACK 키가 눌려졌다고 감지하는 문제가 여전히 남아 있다. 비록 애플리케이션을 SDK 버전 5 이상으로 명시하여 업데이트하는 것 말고는 어떠한 해결책이 없지만, 다행히 BACK 키는 일반적으로 가상 키 영역에서 맨 끝에 위치하기 때문에 사용자는 다른 키와는 달리 BACK 키가 우연히 히트될 가능성이 낮다.

 2.0 이후 및 2.0 이전 버전에 모두 동작하는 애플리케이션을 작성하는 것 역시 대부분의 경우에 매우 쉽다. 예를 들어, 모든 버전의 플랫폼에서 액티비티 내에서 올바르게 BACK 키를 처리하기 위한 코드는 아래와 같다.

 

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
   
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
           
&& keyCode == KeyEvent.KEYCODE_BACK
           
&& event.getRepeatCount() == 0) {
       
// Take care of calling this method on earlier versions of
       
// the platform where it doesn't exist.
        onBackPressed
();
   
}

   
return super.onKeyDown(keyCode, event);
}

@Override
public void onBackPressed() {
   
// This will be called either automatically for you on 2.0
   
// or later, or by the code above on earlier versions of the
   
// platform.
   
return;
}

 

하드 코어용: 올바르게 이벤트 처리하기

 

다룰 가치가 있는 마지막 주제는 onDispatchEvent() 또는 onPreIme() 와 같은 원시 dispatch 함수에서 올바르게 이벤트를 다루는 방법이다. onKeyDown() 과 같은 고수준 함수를 호출할 때 프레임워크가 제공하는 도움을 받을 수 없기 때문에, 이것들에 대해서는 좀 더 많은 주의가 요구된다. 아래 코드는 BACK 키가 릴리즈 될 때 올바르게 액션을 수행하기 위한 BACK 키 처리를 가로채는 방법을 보여준다.

 

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
   
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
       
if (event.getAction() == KeyEvent.ACTION_DOWN
               
&& event.getRepeatCount() == 0) {

           
// Tell the framework to start tracking this event.
            getKeyDispatcherState
().startTracking(event, this);
           
return true;

       
} else if (event.getAction() == KeyEvent.ACTION_UP) {
            getKeyDispatcherState
().handleUpEvent(event);
           
if (event.isTracking() && !event.isCanceled()) {

               
// DO BACK ACTION HERE
               
return true;

           
}
       
}
       
return super.dispatchKeyEvent(event);
   
} else {
       
return super.dispatchKeyEvent(event);
   
}
}

getKeyDispatchState() 호출은 윈도우의 현재 키 상태를 추적하는 데 사용되는 객체를 반환한다. View 클래스에서 일반적으로 사용가능하고 액티비티는 필요하면 그 객체를 가져 오기 위해 임의의 View를 사용할 수 있다.