문제 배경
Android에서 Binding을 처리할 때는 항상 연결과 해제를 구현해줘야 합니다.
class TestFragment : Fragment() {
private lateinit var _binding: FragmentTestBinding
val binding: FragmentTestBinding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) {
_binding = DataBindingUtil.inflate(inflater, R.layout.fragment_test, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
반드시 해제해줘야 하는 이유는 Fragment에서는 생명주기와 Fragment 내의 View 생명주기가 다르기 때문에 onDestroyView매서드가 호출된다 하더라도 binding이 계속 해당 Fragment를 잡고 있어서 메모리 누수를 발생시키기 떄문입니다.
하지만 매번 onDestroyView에서 unbind()를 설정해준다는 것은 생각보다 귀찮고 쉽게 까먹기도 합니다. 따라서 저는 모든 Fragment의 Base가 되는 코드에서 해제해주면 되지 않을까? 라는 생각에 구현하게 되었습니다.
BaseFragment
abstract class BaseFragment<T : ViewDataBinding>(
@LayoutRes private val layoutId: Int
) : Fragment() {
private var _binding: T? = null
val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// binding 연결
_binding = DataBindingUtil.inflate(inflater, layoutId, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.lifecycleOwner = this@BaseFragment
initView()
super.onViewCreated(view, savedInstanceState)
}
// 기존에 onViewCreated에서 초기화하던 코드들을 여기서 구현
abstract fun initView()
override fun onDestroyView() {
super.onDestroyView()
// binding 해제
_binding = null
}
protected inline fun bind(block: T.() -> Unit) {
binding.apply(block)
}
}
반응형
'Android' 카테고리의 다른 글
[Android] API 키 관리하기 - Groovy, KTS (0) | 2023.02.27 |
---|---|
[Image] JPEG, PNG, BMP, GIF, SVG, Webp에 대해 알아보자 (0) | 2023.02.11 |
[Android] Gradle을 KTS로 마이그레이션 하기 (1) | 2023.02.02 |
[Android] OkHttp Interceptor로 서버 Response 변형하기 (0) | 2022.12.22 |
[Android] 에뮬레이터에서 localhost 접속하기 (0) | 2022.12.22 |
댓글