[Error] 액티비티와 프래그g먼트의 의존성 주입 관계

1 분 소요

🙋‍♀️ Error?

Hilt를 사용하던 중 의존성 주입이 필요없는 MainActivity에 @AndroidEntryPoint를 명시해 주지 않았을 때

Error inflating class androidx.fragment.app.FragmentContainerView

해당 오류가 발생했다.


🙋‍♀️ @AndroidEntryPoint

해당 annotation은 hilt에서 di를 사용하는 android 클래스들을 주입 가능한 대상으로 만들어주는 annontation이다.

만약 mainactivity가 주입 가능한 di 대상이 되려면 해당 annotation을 붙이는 게 맞다.


🙋‍♀️ MainActivity


class MainActivity : AppCompatActivity() {
     private val binding: ActivityMainBinding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }
    private lateinit var navController: NavController
    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        setupJetpackNavigation()
    }

    private fun setupJetpackNavigation() {
        val host = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment ?: return
        navController = host.navController

        appBarConfiguration = AppBarConfiguration(
            setOf(R.id.fragment_home)
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}

하지만 아무리 보아도 위의 mainactivity는 di의 대상이 될 필요가 없다! 그래서 그 이유를 열심히 chatgpt에게 물어보았다.


👀 혹시 FragmentContainerView를 사용해?

🧐 Question

mainactivity에 @androidentrypoint를 붙여주지 않았을 때 Error inflating class androidx.fragment.app.FragmentContainerView 해당 오류가 발생하는 데 이유가 뭘까?

🙄 Answer

@AndroidEntryPoint 어노테이션이 없으면 Hilt가 주입할 필요가 있는 클래스를 찾을 수 없기 때문에 오류가 발생합니다. MainActivity에서 Fragment를 사용하는 경우 FragmentContainerView를 사용하므로 해당 오류가 발생할 수 있습니다.

🧐 그렇다면 FragmentContainerView와 의존성 주입이 무슨 관련이 있을까?? 다시 질문해보았다.


🧐 Question

fragmentContainerview를 사용하는 것과 의존성 주입이 무슨 상관이야?

🙄 Answer

그러나 Dagger Hilt를 사용하는 경우, 애플리케이션의 컴포넌트 트리와 Fragment가 호스팅하는 Activity의 컴포넌트 트리 간의 관계를 명확하게 지정해주어야 합니다.

따라서 FragmentContainerView를 사용하는 경우, 해당 Fragment가 속한 Activity에 대해 @AndroidEntryPoint 어노테이션을 사용하여 의존성 주입을 지정해주어야 합니다.

그렇지 않으면 Dagger Hilt가 Fragment의 컴포넌트 트리를 만들 때 호스팅 Activity의 컴포넌트 트리와 관련된 정보가 부족하여 오류가 발생할 수 있습니다.

🧐 Question

그렇다면 컴포넌트 트리를 주입받기 위해 mainactivity에서 @andoridentrypoint를 사용하는 게 맞을까?

🙄 Answer

프래그먼트에서 의존성 주입을 위해 @AndroidEntryPoint를 사용하는 경우, 해당 프래그먼트를 포함하는 액티비티에도 @AndroidEntryPoint를 사용하여 컴포넌트 트리에 접근할 수 있게 됩니다.


🙋‍♀️ 결론

결론은 다음과 같다.

  • activity에 @androidEntryPoint를 붙일 경우, hilt에서는 해당 클래스 내부 프래그먼트들도 주입이 가능하도록 컴포넌트 트리를 생성한다.
  • 따라서 프래그먼트가 의존성 주입에 사용된다면 컴포넌트 트리를 주입받기 위해서 프래그먼트가 속하는 activity도 의존성 주입이 가능해야 한다.


🙇‍♀️ 부족한 부분이 있다면 말씀해주세요! 감사합니다!

댓글남기기