brunch

라이킷 6 댓글 공유 작가의 글을 SNS에 공유해보세요

You can make anything
by writing

C.S.Lewis

소프트웨어 개발자를 위한 Callback의 정석.

by 김경민 Apr 25. 2016

콜백이라는 주제로 첫 게시글을 작성하기 이전에, 브런치의 깔끔하고 세련된 디자인과 UI에 감탄하며...

(하준호 멘토님 감사합니당 ♥)






콜백이란것을 공부하면서. 구글링을 통해 찾은 예제를 수도 없이 보았다.

그러나 콜백이 무엇인지에 대해 뚜렷한 정의를 내리지 못한 채 아몰랑. 답답함만을 느끼던 중


결국, 콜백'A가 B를 호출하여 B가 작업을 수행하다 어떤 시점에서 다시 B는 A를 호출, 그 때 A가 정해놓은 작업을 수행'하는 것.



안드로이드 스튜디오에서 세상에서 가장 간단한(수없이 본 예제중 내가 유일하게 이해함) 콜백을 직접 구현해보았다.


아래의 코드는 MainActivity에서 Callee 클래스의 객체를 생성 후, doWork()를 수행한다. Callee의 doWork()내부에서 또다시 Callee2의 객체를 선언하고 Callee2의 doWork()를 수행한다.


각 doWork()메소드 안에서는 자신을 호출한 메소드로 callback을 보내주도록 되어있다. 메소드 작업을 수행하고 콜백을 수행하는 것을 간단한 Log를 찍어 확인해 볼 것이다.


이 때, Callback은 아래와 같이 Interface로 미리 만들어 놓아 Callback 내용을 부르는 메소드 안에서 구현하도록 강제하였다.


public interface Callback {
    void callback();             // Callback 인터페이스 내의 속이 없는 껍데기 함수
}



public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.i("kkm""MainActivity Log");        // Activity 생성 후 가장 먼저 찍힐 Log
        Callee callee = new Callee();               // Callee 객체 생성
        callee.doWork(mCallback);                // Callee 내의 doWork를 호출

    }


    Callback mCallback new Callback() {     // 인터페이스로 정의한 Callback의 내부를

                                                           // 익명객체로 구현.   
        @Override                                      // callee(위에서 설명한 B)가 호출할 콜백 구현은                                                               MainActivity(A)에서 해준다.
        public void callback() {
            Log.i("kkm""callback1");
        }
    };
}



public class Callee {
    public void Callee() {}
    public void doWork(Callback mCallback) {
        Log.i("kkm""Callee doWork() Log");    // 두번 째로 찍힐 Log
        mCallback.callback();                        // 이 시점에서 MainActivity가 지정한 callback                                                             호출. 세 번째 "callback1" Log가 찍히겠지.

        Callee2 callee2 = new Callee2();           // Callee2 클래스 객체 하나 만들고
        callee2.doWork(mCallback2);             // callee2 안의 doWork()수행. 마찬가지로 Callee를

                                                             참조할 수 있도록 Callee에서 구현한 Callback

                                                              인스턴스 변수 mCallback2를 넘겨줌.
    }                                            
    Callback mCallback2 new Callback() {
        @Override
        public void callback() {
            Log.i("kkm""callback2");             // 다섯번 째로 직힐 callback2 Log.
        }
    };
}


public class Callee2 {
    public Callee2() {}
    public void doWork(Callback mCallback) {     // callee로부터 doWork가 호출되면 수행.
        Log.i("kkm""Callee2 doWork() Log");      // 네 번째 Log를 찍고
        mCallback.callback();                            // Callee에서 지정한 callback함수 호출  
    }
}




실행. logcat에서 다음과 같이 Log가 찍힌 것을 볼 수 있었다. 

kkm: ManiActivity Log

kkm: Callee doWork() Log

kkm: callback1

kkm: Callee2 doWork() Log

kkm: callback2


아래의 그림은 Log찍히는 순서를 나타낸 것.

브런치 글 이미지 1




다시한번 정리를 하면,

콜백function이 자신의 일부를 넘기는 행위이다.

즉, A가 B를 호출하는데 B가 A의 일부분을 실행시켜 달라는 소리다.

B가 A가 지정해 놓은 '일부분'을 수행하기 위해 A를 참조해야 하는 데 그 수단으로 위에서 처럼 클래스 자신의 인스턴스 변수를 넘긴 것이고, 호출한 메소드가 자신의 인스턴스 변수를 이용하여 자신의 메소드를 호출할 수 있게 하는 것이다.


끝!

브런치 로그인

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari