-
Fragment에서 ViewBinding 사용 시 발생할 수 있는 메모리릭Android 2020. 11. 13. 12:03
Fragment에서 두 가지 생명주기
Fragment는 Activity와 다르게 조금은 다른 생명주기를 가지고 있습니다. Fragment의 고유한 생명주기를 가지고 있으면서도 자세히 보면, View와 관련된 생명주기도 가지고 있죠.
위의 이미지를 보시면 onCreateView와 onDestroyView를 가지고 있는 것을 확인할 수 있습니다. onCreate와 onCreateView라는 두가지 생명주기를 가지는데 이 둘의 차이가 무엇일까요? onCreate는 Fragment가 생성될 때, 즉 화면이 아직 보이지 않는 상태에서 실행되는 것이고, onCreateView는 화면을 구성할 때 호출되는 부분입니다. 그래서 직접적으로 화면과 관련된 생명주기는 onCreateView와 onDestroyView가 되는 것이죠.
Fragment BackStack과 메모리릭 위험성
Fragment A에서 B로 Replace한다고 해볼까요? 이 때, Fragment A의 모든 View 요소들은 제거됩니다. 하지만, Fragment A의 instance는 그대로 남아서 backStack에 저장이 될거에요. 그런데 Fragment A에서 View와 관련되지 않은 요소들은 어떻게 될까요? 아마 A의 instance에 그대로 종속되있을 것입니다. 여기서 메모리 릭의 가능성이 생깁니다.
open class BaseBottomSheetDialogFragment<VDB : ViewDataBinding> : BottomSheetDialogFragment() { @LayoutRes protected open val layoutResId: Int = 0 protected lateinit var viewDataBinding: VDB override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { viewDataBinding = DataBindingUtil.inflate(inflater, layoutResId, container, false) return viewDataBinding.root }
저는 BottomSheetDialogFragment를 상속한 BaseBottomSheetDialogFragment 클래스를 만들었습니다. 이 클래스는 viewDataBinding이라는 변수를 lateinit으로 선언했고, onCreateView에서 초기화가 이루어집니다. 하지만 초기화가 이루어지고 만약 다른 Fragment로 교체된다면 이 viewDataBinding은 이미 참조하고 있는 것이 있기 때문에, Destroy되지 않고 그대로 backStack에 남게 됩니다. 그래서 메모리 릭이 발생할 수 있는 것인데요. 이를 해결하려면 어떻게 해야할까요?
open class BaseBottomSheetDialogFragment<VDB : ViewDataBinding> : BottomSheetDialogFragment() { @LayoutRes protected open val layoutResId: Int = 0 protected var viewDataBinding: VDB? = null override fun onDestroyView() { super.onDestroyView() viewDataBinding = null }
위와 같이 viewDataBinding을 null로 초기화 한 후, onCreateView에서 다시 DataBindingUtil을 통해 할당하고, 마지막으로 view가 소멸되는 시점인 onDestroyView에서 viewDataBinding을 null로 초기화시켜줍니다. 이렇게 하면 메모리 릭에 대한 위험을 제거할 수 있습니다.
'Android' 카테고리의 다른 글
Two-way Binding 사용법 (0) 2020.12.22 onBackPressed와 finish의 차이 (0) 2020.12.04 변수의 동시성 제어에 관한 이슈 및 해결 (1) 2020.10.27 Gson을 통해 API Response를 Enum으로 매핑하기 (0) 2020.09.25 [안드로이드 9.0 프로토콜 접속 변경사항] CLEARTEXT communication to XXXX not permitted by network security policy (0) 2020.07.24