본문 바로가기
오늘은 뭘 배울까?/Android

콜백 함수(Callback function)란 무엇일까?

by Kim Juhwan 2021. 2. 16.

 

오늘은 콜백 함수에 대해 공부하기로 했다.

사실 이번에 토이 프로젝트를 하기 전까지는 콜백 함수가 뭔지 몰랐다.

아니 존재 자체도 몰랐다.

보고 따라 사용하면서도 내가 잘 이해하면서 쓰고 있는 건가..? 싶었다.

 

안드로이드 개발자 오픈채팅방

예전에 오픈 채팅방에 뭘 물어봤었는데 이런 답변을 해주신 분이 계셨다

정곡을 찔린듯한 기분이 들었다.

"인터넷보고 따라 작성해서 어찌저찌 코드는 돌아갔다고 해도 그건 니 코드가 아니다"를 좋게 말씀해주신 것 같다.

그래서 오늘은 콜백 함수 파헤치기!! 빠밤

 

 

 


 

 

1. 이해하기 쉽게 실생활에 빗대어 만화로 그려보았다.

 

이렇게 해서 모두가 행복하게 살았답니다(?) 끝 -!

 

 

불쌍한 우리 메인작가...

모든걸 혼자서 다 하기엔 시간이 오래 걸리는 모양이다.

결국 원고도 못 그리고 큰일날 뻔했지만

보조작가의 도움으로 오래걸리는 작업은 맡겨두고, 계속해서 원고를 그려나갈 수 있었다.

보조작가가 작업이 다 끝나면 전화를 해주기로 했다.

전화를 받으면 그때 그 스토리로 다음 원고를 그려나가기로 했다.

 

이 이야기에는 동기/비동기 그리고 콜백 함수의 개념이 녹아들어 있다.

그럼 이제 프로그래밍 관점에서 이야기를 다시 보자!

 

 

 

2. 프로그래밍 관점으로 이야기를 바꿔보았다.

 

 

이렇듯 메인 스레드에게 네트워크나 DB작업 같이 오래 걸리는 일을 맡기는 건 옳은 방법이 아니다.

사용자는 UI가 그려질 때까지 백날이고 천날이고 기다려주지 않기 때문이다.

그래서 우리는 메인 스레드 외에 다른 스레드를 사용하는 것이고

그 스레드에게 일을 시켜놓고 내 할 일을 하는 것이 비동기인 것이다.

(내가 그 일을 순서대로 진행하면 동기)

 

그리고 마지막으로...

다른 스레드에게 일을 시켜놓고 메인 스레드는 계속해서 UI를 그려나간다.

작업을 다 마친 스레드가 결과물을 메인 스레드에게 넘겨주면

메인 스레드는 그걸 이용해서 UI를 그린다.

이때 "메인 스레드님!! 저 작업 다 끝났어요!!라고 하는 게 콜백인 것이다.

 

 

 

3. 콜백 함수를 사용한 실제 예시

recyclerView_notices.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        if (!recyclerView_notices.canScrollVertically(1){
            공지사항을 불러옴(네트워크 작업)
            리스트에 공지사항을 추가하고 새로고침(UI 작업)
        }
})

위 코드를 작성하면서 콜백 함수의 필요성을 느끼게 되었다.

recyclerView의 끝에 도달하면 네트워크에서 다음 공지사항을 가져와서 화면에 보여주는 코드이다.

네트워크 작업이 오래 걸리기 때문에 UI 작업이 먼저 실행되었고

그 결과 오류가 생기는 일이 발생했다.

 

 

 

[코틀린] infinite/endless scroll(무한 스크롤)과 recyclerView

1. infinite/endless scroll  1-1. 개념  1-2. Progress Bar  1-3. 아이템 뷰(ItemView)  1-4. 홀더(Holder)  1-5. 스크롤 리스너(Scroll Listener)  1-6. 다른 최하단 도달 감지 방법 2. Adapter  1-1...

todaycode.tistory.com

(혹시 위 코드에 대한 자세한 내용이 궁금하다면 여기서 다루고 있다)

 

 

interface PostListener {
    fun loadPage(notices: ArrayList<NoticeList>)
}

아무튼...

그래서 네트워크 작업이 끝나면 콜백을 해서 UI 작업을 하도록 해야 했다.

그러기 위해서는 우선 콜백 함수를 만들어야 한다. 여기서는 loadPage라는 이름으로 정했다.

 

이 loadPage는 메인 액티비티에서 정의할 것이므로 interface안에 선언한다.

 

 

class MainActivity : AppCompatActivity(), PostListener { // PostListener를 구현한다.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        recyclerView_notices.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)

                if (!recyclerView_notices.canScrollVertically(1){
                    네트워크 작업(this) // this는 listener를 뜻한다.
                    // 여기서 했던 UI 작업을 loadPage 함수에서 한다.
                }
            }
        })
    }
    
    override fun loadPage(notices: ArrayList<NoticeList>) { // override 함
        UI 작업
    }
}

메인 액티비티에서 PostListener를 구현하고 loadPage를 재정의 해준다.

그러면 이제 리스트 UI 작업은 별도의 함수에서 정의되어있고

콜백을 받았을 때 실행 되게 될 것이다.

 

class 네트워크 작업(listener: PostListener){
    var mCallback = listener
    ...
    ...
    ...
    mCallback.loadPage(notices) // 작업이 다 끝나고 loadPage를 호출한다.
}

네트워크 작업을 하는 곳에서 뚝딱뚝딱 일을 처리해서

공지사항 목록인 notices를 만들고

그 결과물을 loadPage를 통해 넘겨주게 된다.

이제 비로소 UI 작업을 할 수 있게 되는 것이다.

 

 

 


 

 

 

참고한 영상

https://www.youtube.com/watch?v=s1vpVCrT8f4

https://www.youtube.com/watch?v=jjypeFGJC3c

 

 

 

[kotlin] 코루틴 공부하기 (비동기 처리, 서버 딜레이 처리)

빌어먹을 코루틴... 저번에 공부하다가 도저히 못해먹겠어서 포기했다가 오늘 다시 도전했다. 항상 느끼는 거지만 아무것도 모를 땐 그렇게 어렵게 느껴지다가 또 막상 성공하면 아 이걸 왜 이

todaycode.tistory.com

비동기 처리도 배우고 가셔유!

반응형

댓글