[TIL] (2023/10/02) 공유기능 Context 전달, 제네릭 사용

Start!

오늘은 팀 프로젝트 제출 이틀 전이다. 실질적인 시간이 없었기 때문에 오늘은 거의 하루종일 코딩만 하였다..!! ViewModel을 자주 다루며 데이터를 전달하던 중 제네릭을 적용해보았고 Util Object안에 공유기능을 넣으면서 Context를 전달한 것에 대해 가볍게 적어보려고 한다 🙂

다른앱으로 데이터 공유 Context 전달

이번 팀 프로젝트를 진행하며 Youtube URL을 다른 앱으로 전송하는 기능을 구현하였는데 기능을 따로 Util Object로 빼주기 위해 다음과 같이 함수에 Context를 넘겨줄 일이 생겼다.

  • Contex를 넘겨주는 방식에 있어서 고민을 좀 했는데
  • 기존엔 생각 없이 requireContextactivity as MainActivity로 액티비티 캐스팅을 때려넣어주는 방식을 사용했는데
1. Util.shareUrl(requireContext(), detailItem.imgUrl)

2. Util.shareUrl(activity as MainActivity, detailItem.imgUrl)
  • 좀 더 생각을 하다보니 requireContext()는 context가 null일 경우 IllegalStateException 발생한다는 것을 알게되었고

  • activity as MainActivity 이 방식 또한 생명주기 등으로 인해 안정성에서 문제가 있다는 것을 알게 됐다.

public final Context requireContext() {
        Context context = getContext();
        if (context == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to a context.");
        }
        return context;
    }
최종코드
  • 그래서 context를 넣어줄 때 activity를 널체를 통해 안정성을 보장하는 방식으로 구현하였다 :)
final public FragmentActivity getActivity() {
    return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}
activity?.let { context ->
    viewModel.detailItem.value?.let { detailItem ->
        Util.shareUrl(context, detailItem.imgUrl)
    }
}
클릭!! ⬅︎ 기능에 대한 설명은 여기 링크에 작성해놓았다 !!

제네릭

다음은 제네릭인데 사실 제네릭을 알고만 있고 제대로 사용해본 적이 거의 없었는데 이번에 처음 사용함으로서 그 편리함을 알아버렸다..!

  • 다음은 MainSharedViewModel에서 _homeEvent LiveData를 다루는 코드이다.
  • updateHomeItems는 Detail,Bookmark Fragment 두 곳에서 사용하는데 각각 DetailModel, BookmarkModel을 파라미터로 넘겨주고 toHomeModel()확장함수를 통해 HomeModel로 매핑하게 된다.
기존의 코드
  • 기존의 코드는 각각 Fragment에서 데이터를 전달할 때 다른 Fragment에 해당하는 Model엔 null을 집어넣어 비효율적으로 파라미터를 넘겨줬지만
// DetailFragment
updateHomeItems(detailModel = detailModel, bookmarkModel = null)
// BookmarkFragment
updateHomeItems(detailModel = null, bookmarkModel = bookmarkModel)
fun updateHomeItems(detailModel: DetailModel?, bookmarkModel: BookmarkModel?) {
    val detailModel = when {
        DetailModel != null -> detailModel.toHomeModel()
        BookmarkModel != null -> bookmarkModel.toHomeModel()
        else -> return // 모든 변수가 null인 경우     
    }
    _detailEvent.value = MainSharedEventForDetail.UpdateDetailItem(detailModel)
}
제네릭을 사용한 코드
  • 제네릭을 사용해 판단만 ViewModel 내부에서 처리하여 좀 더 간결하고 보기 편한 코드가 되었다 :)
// DetailFragment
updateHomeItems(detailModel)
// BookmarkFragment
updateHomeItems(bookmarkModel)
fun <T> updateHomeItems(updateModel: T?) {
    val homeModel = when (updateModel) {
        is DetailModel -> updateModel.toHomeModel()
        is BookmarkModel -> updateModel.toHomeModel()
        else -> return
    }
    _homeEvent.value = MainSharedEventForHome.UpdateHomeItem(homeModel)
}

느낀점

요즘 계속해서 어떻게 하면 보기좋은, 효율적인 클린코드일까를 많이 고민하는것 같다.

물론 내 코드들보다 훨씬 더 좋은 코드들이 많겠지만 차근차근 리팩토링 해가며 발전하는 재미가 있는 것 같다 :)

End!

얼마 안남았으니까 더 열심히 해야겠다 끝 ~!!


© 2023. All rights reserved.

by SoftyChoo