[컴][안드로이드] invalidate() 과 postInvalidate() 의 차이

invalidate() vs postInvalidate()

invalidate() 가 불려지면, 전체 view를 invalidate() 합니다.(무효화?) view 가 보여지면(visible) 미래의 어느시점에 onDraw()를 호출하게 됩니다.

근데 invalidate() 는 ref.2 에서 얘기하듯이 UI thread 에서만 사용할 수 있습니다.

처음 안드로이드 애플리케이션을 시작할 때마다, “main” 이라고 불리는 하나의 쓰레드가 자동으로 생성됩니다. 이 main thread 가 UI thread 입니다.[ref. 5]

일단 ref. 1 에서 설명하듯이 invalidate() 는 UI thread 에서만 사용할 수 있습니다. 아니면 CalledFromWrongThreadException() 가 발생하게 됩니다.[ref. 1]

그렇기 때문에 외부에서 이 함수를 호출할 수 없습니다. 그래서non-UI thread 에서는 postInvalidate()를 호출해야만 합니다.

Analyzing

근데 조금 설명이 빈약해서 분석을 좀 해봐야 할 듯 합니다. 아래에 대략적으로 분석한 내용입니다.
postInvalidate() 는 INVALIDATE_MSG 를 UI event queue 에 넣게 됩니다. 이것을 handler 가 가져다 처리하는 듯 합니다.(분석을 대충해서 확실치 않습니다. ^^;)  

반면에 invalidate() 은 직접적으로 dirt() 를 set 하는 것으로 보아 invalidate 영역을 실제로 지정하는 듯 합니다..(분석을 대충해서 확실치 않습니다. ^^;)

아직 분석을 더 해봐야 겠네요. 일단 바빠서 …^^;;;

postInvalidate() 은 아래 함수를 호출 합니다.

  • attachInfo.mHandler.sendMessageDelayed(msg, delayMilliseconds);

이 함수는 일정 시간후에 msg 를 처리하도록 해주는 것인데, 이 함수를 이용해서, queue 에 msg 를 보낼때 일정시간이후에 처리가 가능하도록 해주는 듯 합니다.

일단 지금까지 생각으로 이녀석이 없어도 되는데, 이녀석을 만드는 이유는 다른 thread 에서 handler 를 통해서 invalidate() 를 호출해야 하는 작업이 빈번이 일어나니, wrapper method 를 하나 만든 듯 합니다.

그리고 현재 ui thread 에 있는 상태에서라면, postInvalidate() 가 어떤 장점을 갖는지 잘 짐작되지 않는다. 하나 짐작되는 것은 invalidate() 가 좀 더 빠르게 화면을 redraw 하도록 만들것이라는 것이다.

 반대로 말하면, postInvalidate() 가 좀 덜 빠르게 화면을 refresh 하도록 요청할 것이라는 것이다.(물론 여기서 조금 덜 빠르다는 것은 cpu clock  단위의 얘기이다. postInvalidate() 를 사용해도 아마 user 가 느끼는 빠르기엔 크게 변함이 없을 수도 있다.)


References

  1. 안드로이드에서 Handler 사용? #1
  2. http://stackoverflow.com/questions/6120432/why-invalidate-must-be-called-by-ui-thread
  3. postInvalidate() API 문서
  4. What does postInvalidate() do?
  5. [번역] Painless threading
  6. http://stackoverflow.com/questions/7596370/what-is-the-difference-between-androids-invalidate-and-postinvalidate-metho

댓글 2개:

  1. 좋은 정보 감사합니다. 글을 읽으면서 궁금한 것이 있어서 여쭤봅니다.
    그렇다면 rendering이 끝나는 시점을 알 수 있다는 것인가요??
    (onPageFinished는 loading이 끝난 것이지 rendering이 끝난게 아닌 것이라..)

    답글삭제
    답글
    1. 저도 잘 몰라서 좀 찾아보니, 아래 글이 있네요. ViewTreeObserver 를 이용하시면 될 듯 하네요.
      http://stackoverflow.com/questions/5623194/android-call-back-after-layout-rendering-has-completed

      삭제