2017년 10월 23일 월요일

Conductor 소스 분석


Conductor
  • MainActivity: 최상단 activity
    • Conductor.attachRouter를 통해 Activity와 Activity 안의 container(FrameLayout으로 만든다.)와 savedInstanceState를 연결하는 Router를 만든다.
    • attachRouter: LifecycleHandler라는 Fragment를 만들어서 Activity에 연결한다. 실제 Router는 LifecycleHandler에서 만든다.
  • Router: stack을 통해 Controller의 go/back을 관리한다.
    • Router의 setRoot를 통해 최상단에 적용할 Controller를 연결한다. Controller는 RouterTransaction을 통해 Router에 연결된다.
  • Controller: inflateView를 통해 View를 연결한다.
  • ControllerChangeHandler: View의 변환시 Animation이나 Transition을 한다.

LifecycleHandler

  • Fragment를 상속한다.
  • setRetainInstance(true)를 통해 activity가 recreate될 때 fragment도 같이 recreate되지 않도록 한다.
  • activeLifecycleHandlers를 통해 activity마다 하나의 LifecycleHandler를 연결한다.
  • application에 자신을 ActivityLifecycleCallbacks으로 등록한다.
  • pendingPermissionRequests: 퍼미션 요청하는 것에 대한 관리
  • routerMap을 통해 container(ViewGroup)마다 하나의 ActivityHostedRouter를 연결한다.

Router

  • ActivityHostedRouter and ControllerHostedRouter
  • ActivityHostedRouter는 LifecycleHandler와 연결하고, ControllerHostedRouter는 Controller와 연결한다.
  • InstanceState를 써서 data를 유지한다: KEY_BACKSTACK, KEY_POPS_LAST_VIEW
  • setRoot를 통해 최상단 RouterTransaction을 연결한다.
    • BackStack에 RouterTransaction을 넣는다.
    • ControllerChangeHandler.executeChange를 통해 RouterTransaction의 Controller에 연결되어 있는 View를 addView한다. 이전것은 removeView한다.
    • add와 remove를 위해 ControllerChangeHandler를 사용한다. RouterTransaction에 연결된 ControllerChangeHandler가 없으면 애니메이션없는 SimpleSwapChangeHandler를 사용한다.
  • Backstack
    • ArrayDeque을 통해 백스택 구현
    • Iterator<RouterTransaction> 및 reverseIterator 제공
  • Backstack에 controller가 들어가면 아래의 라이프 관련 함수가 호출된다.
    • onContextAvailable
    • inflate
  • Backstack에서 controller가 빠지면 아래의 라이프 관련 함수가 호출된다.
    • detach
    • destroy

ControllerChangeHandler

  • Controller로부터 View를 얻어온다: inflate
  • performChange를 통해 View의 push/pop을 실행한다.
  • AnimatorChangeHandler
    • performChange 함수에서 addView를 하고 animation을 시작한다.
    • animation은 subclass의 getAnimator를 통해 얻어온다.
    • FadeChangeHandler: AnimatorChangeHandler를 상속하여 getAnimator와 resetFromView를 구현
      • getAnimator: AnimatorSet를 사용하여 기존의 뷰는 알파를 0으로, 새로운 뷰는 알파를 0에서 1로 변경한다.
      • resetFromView: 애니메이션이 끝나면 호출되는 함수. 기존의 뷰의 알파를 1로 바꾼다.

Controller

  • instanceId: UUID.randomUUID().toString()
  • 화면의 구성을 위해 inflate가 호출된다.
    • onCreateView를 호출하여 View를 생성한다.
    • subclass에서 inflateView와 onViewBound를 구현한다.
  • detach시 onSaveViewState를, inflate시 onRestoreViewState를 호출해준다.

RouterTransaction

  • Controller와 (pushChangeHandler, popChangeHandler)의 연결고리를 Router에 제공한다.

Lifecycle 관리

  • LifecycleHandler는 ActivityLifecycleCallbacks를 구현한다.
    • ActivityLifecycleCallbacks는 Application에 선언되어 있는 인터페이스이다.
    • 콜백이 불리면 Router의 Lifecycle 관련 함수를 호출한다.
  • Router는 Lifecycle 관련 함수를 정의하고 있다.
    • 이 함수에서는 Controller의 Lifecycle 관련 함수를 호출한다.
    • child router가 있으면 이의 Lifecycle 관련 함수를 호출한다.
  • LifecycleListener
    • Controller에 등록해서 Lifecycle 이벤트를 받는다.

AutoDispose

  • ControllerScopeProvider
    • Controller에서 라이프 사이클이 바뀌면 BehaviorSubject를 통해 이벤트가 발생하도록 한다.
    • lifecycle에서 아이덴티티를 숨긴 lifecycleSubject.hide()를 리턴한다.
    • correspondingEvents에서 dispose를 하기 위해 대응되는 매핑(CORRESPONDING_EVENTS)을 리턴한다.
    • peekLifecycle에서 BehaviorSubject의 현재 값을 리턴한다.

댓글 없음:

댓글 쓰기

Building asynchronous views in SwiftUI 정리

Handling loading states within SwiftUI views self loading views View model 사용하기 Combine을 사용한 AnyPublisher Making SwiftUI views refreshable r...