dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper cannot be cast to android.app.Activity
Asked Answered
T

4

21

I'm using a third-party library that has some custom view implementations. In the implementation, they call Utils.showSoftKeyboard(context as Activity). This, along with using the fragment as an @AndroidEntryPoint causes the following exception:

java.lang.ClassCastException: dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper cannot be cast to android.app.Activity.

Is there any way to fix this without altering the third-party library?

Tarsus answered 13/10, 2020 at 18:51 Comment(0)
A
14

If the third-party library has an issue tracker, it's a good idea to raise an issue about this. There is no guarantee that the context of a View is an Activity: the same problem can be caused just as easily by an android:theme attribute in the custom view or any ancestor.

If you don't inflate any @AndroidEntryPoint views in your fragment, you can work around this by getting a LayoutInflater directly from the activity context.

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val baseInflater = LayoutInflater.from(requireActivity()) // NOT context
        // ...
    }
Adaptable answered 13/10, 2020 at 20:11 Comment(0)
C
7

Without Hilt Dependencies we can access parent activity as below

(context as ContextWrapper).baseContext

Careworn answered 16/6, 2021 at 20:9 Comment(0)
P
5

It might be late for your problem but here's a solution which might help others having the same problem. You basically should check the context type before trying to cast it.

  val mContext = if (context is ViewComponentManager.FragmentContextWrapper)
            context.baseContext
        else
            context

Inspired by this answer.

Penumbra answered 9/2, 2022 at 15:45 Comment(0)
P
1

Based on the answer by Nitrodon, I found the solution. I was using Hilt with view bindings and my code looked like:

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

I had to do:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    val baseInflater = LayoutInflater.from(requireActivity())
    _binding = FragmentGoalsBinding.inflate(baseInflater, container, false)
    return binding.root
}

I was also inflating my viewModel with a viewModel Provider and that was a crash (no init<> method), and I then used by viewModels(). Voila! The code ran

Phira answered 8/11, 2023 at 15:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.