[안드로이드] BaseActivity, BaseFragment

hee09·2022년 3월 6일
0
post-thumbnail

반복되는 코드 줄이기

Activity와 Fragment에서 Data Binding을 선언하다보면 아래와 같은 중복되는 코드가 생겨납니다.

class SampleActivity: AppCompatActivity() {
    private lateinit var binding: ActivitySampleBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		// Databinding 초기화
        binding = DataBindingUtil.setContentView(this, R.layout.activity_sample)
        binding.apply {

        }
    }
}

긴 코드는 아니지만 모든 Activity와 Fragment에 위와 같은 코드를 추가한다는 것은 번거롭고, 이와 같은 Bolierplate 코드가 추가되는 것은 좋지 않다고 생각합니다. 이에 대한 해결 방법은 BaseActivity 또는 BaseFragment를 만들고, 이를 상속해서 사용하는 것입니다.


BaseActivity, BaseFragment

BaseActivity와 BaseFragment는 추상 클래스 또는 open 클래스로 선언하여 다른 Activity(Fragment) 클래스에서 이를 상속해서 사용할 수 있도록 만듭니다. 예제 코드에서는 추상 클래스로 선언하였습니다.

BaseActivity

abstract class BaseActivity<T: ViewDataBinding>(@LayoutRes val layoutRes: Int)
    : AppCompatActivity() {
    protected lateinit var binding: T

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 초기화된 layoutResId로 DataBinding 객체 생성
        binding = DataBindingUtil.setContentView(this, layoutRes)
        // LiveData를 사용하기 위한 lifecycleOwner 지정
        binding.lifecycleOwner = this@BaseActivity
    }

}

BaseActivity를 상속

class SampleActivity: BaseActivity<ActivitySampleBinding>(R.layout.activity_sample) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.apply {

        }
    }
}

BaseFragment

abstract class BaseFragment<T: ViewDataBinding>(@LayoutRes val layoutRes: Int)
    : Fragment() {
    lateinit var binding: T

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, layoutRes, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        binding.lifecycleOwner = this@BaseFragment
        initView()
        super.onViewCreated(view, savedInstanceState)
    }

    abstract fun initView()
}

BaseFragment를 상속

class FragmentSample: BaseFragment<FragmentSampleBinding>(R.layout.fragment_sample) {
    override fun initView() {
        binding.apply {
            
        }
    }
}

장점

  • 예제에서는 데이터 바인딩만을 Base에 선언하였지만 이뿐만 아니라 Activity나 Fragment들이 공통적으로 수행해야 하는 코드가 있다면 Base를 이용하여 공통 코드를 뽑아낼 수 있습니다.
  • 공통적으로 코드를 뽑아내기에 Boilterplate 코드가 줄어듭니다.

주의사항

다만 주의할 점은 아래와 같은 문제들을 인지하고 BaseXXX 를 설계하는 걸 추천합니다.

  • Lifecycle를 꼭 지키도록 설계해야 합니다.
  • 특정한 Activity가 상속되어야 할 경우는 애초에 BaseActivity를 쓰지 않고 필요한 것들을 Interface에 정의해놓고 이를 Implemets하여 사용합니다.
  • BaseActivity를 사용하다보면 내용이 점점 많아져서 Base의 의미를 잃는 경우가 생길 수 있습니다. 따라서 BaseActivity 또한 아래와 같이 분리해서 사용합니다.
    • BindActivity
      • MvvmActiviy
        • MainActivity

참조
안드로이드 Data Binding(데이터 바인딩) 반복되는 코드 줄이기
안드로이드 익숙한 BaseXXX class를 알아보고, 설계의 중요성을 알아보자.

틀린 부분은 댓글로 남겨주시면 수정하겠습니다..!!

profile
되새기기 위해 기록

0개의 댓글