[ActionScript] Event 클래스의 target과 currentTarget 속성

플래시의 기능을 최대한 할용하고는 있지만… 플래시가 자동으로 처리해주는 것보다는… 퍼포먼스 향상을 목표로 부하를 최소화하기 위해.. 수동으로 처리해주는 기능들이 있습니다..

예를 들어서 Sprite 클래스가 가지고 있는 자식들 각각에 대해 클릭 이벤트를 받아 오기 위해.. 각 자식들에 대해 마우스 이벤트를 등록(addEventListener)를 하지 않고… 부모 Sprite에만 마우스 이벤트를 등록해 놓고.. 이 부모의 이벤트에서 자식들의 클릭 여부(hitTestPoint 매서드를 사용)를 가려내고자 함입니다..

이때… 클릭한 지점에 대한 좌표가 여러 모로 혼란스럽습니다… 플래시 자체가 DisplayObject라는 레이어로 첩첩히 쌓여져 있어서… 말입니다.. 여담이지만.. GIS의 지도 레이어 개념과 플래시의 DisplayObject의 대응은 마치 플래시를 맵엔진을 위해 만들어지 개발환경이 아닌가할 정도로… 뛰어납니다…

다시 본론으로 돌아와서… 부모 Sprite에서 받은 마우스 클릭 위치에 대해서 자식 Sprite의 hit 여부를 알아내기 위해서는 마우스 이벤트의 인자인 Event 클래스의 target를 제대로 이해하고 있어야 합니다.. target와 함께 currentTarget 속성이 존재하는데.. 간단히 정리하면 다음과 같습니다..

  • target : 이벤트를 dispatch한 객체
  • currentTarget : 이벤트 핸들러 함수가 등록된 객체

다음 코드는 진행중인 플래시 기반의 맵엔진의 코드중.. 이와 관련된 부분입니다..

public function mouseClick(e:MouseEvent):void
{
    ....

    if(_targetLyr != null)
    {
        var pt:Point = new Point(e.localX, e.localY);
        pt = (e.target as DisplayObject).localToGlobal(pt);

        // 내부적으로 Sprite의 hitTestPoint(pt.x, pt.y)가 사용됨
        _sketch = _targetLyr.getIdByPoint(pt.x, pt.y);
        if(_sketch != null)
        {
            _sketch.draw(_map.coordMapper);

           ....
        }
    }

    ....
}

보시면… 위의 mouseClick 매서드는 이벤트가 아닙니다.. 단지 mouseDown과 mouseUp 이벤트를 조합해서 클릭 여부에 대해 형성된 이벤트 성격의 매서드입니다.. 여튼.. 이벤트라고 생각하셔도 무방합니다..

이 mouseClick 매서드는 부모 Sprite의 소유입니다.. 즉, 달리 말해 부모 Sprite에 등록된 이벤트입니다. 이때 받은 e 매개변수에 localX과 localY 좌표는 클릭된 위치이고… 클릭된 위치는.. 부모 Sprite일수도 있고… 자식 Sprite일수도 있습니다.. 즉, 이 이벤트가 등록된 부모에 대한 좌표가 아니라는 점입니다..

문제는 Sprite의 hitTestPoint가 받는 x, y 좌표입니다.. 받는 x, y 좌표는 부모 Sprite의 좌표여야 하는데.. e를 통해 넘어온 좌표는 부모의 좌표일수도.. 자식의 좌표일 수도 있다는 점입니다.. 이를 부모의 좌표로 통일해줘야 하는데.. 그 방법이 바로 8번 코드의 target를 속성을 사용하는 것입니다.

플래시의 DisplayObject의 개념과 target 속성에 대한 기본적인 부분을 알면 매우 당연한 내용이겠지만…. 저처럼.. 플래시에 대한 개념이 얕은 사람은.. 매우 혼돈스러운 부분이 아닐까 싶습니다..

[안드로이드] SD 카드에 파일 생성

안드로이드는 보안상의 이유로 모바일 디바이스의 내장 메모리를 통한 파일을 여러개의 어플리케이션에서 공유하는 것이 여러모로 불편하게 되어 있습니다. 하지만 외장 메모리인 SD 카드의 경우는 이러한 제약이 존재하지 않습니다. 이 글은 안드로이드에서 SD 카드에 파일을 생성하는 것에 대한 정리입니다.

먼저 안드로이드에 SD 카드의 사용 가능 여부를 판단하기 위한 코드는 아래와 같습니다.

String ess = Environment.getExternalStorageState();
String sdCardPath = null;
if(ess.equals(Environment.MEDIA_MOUNTED)) {
    sdCardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
    showMsg("SD Card stored in " + sdCardPath);
} else {
    showMsg("SD Card not ready!");
}

showMsg는 안드로이드의 Toast 기능을 좀더 쉽게 사용하기 위한 사용자 정의 매서드로써 아래와 같습니다.

private void showMsg(String msg)
{
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}

Toast는 디바이스 화면에 일정 시간 동안 메세지를 띠워주는 기능입니다. 다시 본론으로 돌아가서.. 정적 클래스인 Environment의 getExternalStorageState 매서드의 반환값이 Environment.MEDIA_MOUNTED 인 경우가 SD 카드를 사용할 수 있다는 의미이고 사용 가능하다면 SD 카드가 마운트된 디렉토리 명을 얻기 위해 다시 Environment의 getExternalStorageDirectory 매서드를 사용합니다. 이렇게 얻은 디렉토리에는 보안상의 제약 없이 자유롭게 파일을 읽고 쓸 수 있습니다. 여기서는 파일을 쓰는 코드에 대해 살펴보겠습니다.

File file = new File(sdCardPath + "/test.txt");
try {
    FileOutputStream fos = new FileOutputStream(file);
    String msg = "이 파일은 SD 카드에 저장된 메세지입니다.";
    fos.write(msg.getBytes());
    fos.close();
} catch(FileNotFoundException fnfe) {
    showMsg("지정된 파일을 생성할 수 없습니다.");
} catch(IOException ioe) {
    showMsg("파일에 데이터를 쓸 수 없습니다.");
}

안드로이드는 자바 언어를 통해 플랫폼의 API를 사용할 수 있습니다. 이런 맥락으로 SD 카드에 파일을 생성하고 읽고, 쓰기는 자바의 API를 그대로 사용할 수 있습니다.

끝으로 SD 카드를 사용하기 위해서는 매니페스트 파일에 다음과 같은 설정값을 추가해줘야 합니다.


이 설정값이 없다고 해도 SD 카드를 사용할 수 있다고 나오지만 실제로 파일을 쓰거나 읽을 수 없으니.. 반드시 이 설정값을 추가하기 바랍니다.