24

In my code I was inconveniently loading pictures after onCreateView() because I was not sure if the activity was available yet. Because Glide required an activity context I placed the section of code into onActivityCreated():

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

    //Crash unexpected since onActivityCreated should always have activity available
    Glide.with(activity!!)
        .load(viewModel.moment!!.mediaPath)
        .into(binding.momentPhoto);
}

However, after looking through some best practices on Github many examples load the photos in onCreateView(). They do this by using the requireActivity() method:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_photo_editor, container, false)

    Glide.with(requireActivity())
          .load(viewModel.moment!!.mediaPath)
          .into(binding.momentPhoto);

    return binding.root
}

Does anyone know what the difference between using an activity reference after onActivityCreated() and getting the activity reference from requireActivity()?

GSerg
  • 76,472
  • 17
  • 159
  • 346
chrisdottel
  • 1,053
  • 1
  • 12
  • 21

3 Answers3

35

We should split this answer in two parts.

1. The difference between activity!! and requireActivity()

They both invoke getActivity() and they both throw an exception if the Activity is null. The only difference is the type of the returned exception and its message. Certainly, requireActivity() throws a more explicit exception.

2. The "difference" between onActivityCreated() and onCreateView()

The method onActivityCreated() is invoked after onCreateView() when both the Activity and the Fragment view are already created.

The method onCreateView() is invoked before onActivityCreated() when the Fragment view should be still created.

In your scenario, there's no difference in where you put your Glide usage. It would have been a difference if your Fragment retains its instance or in the case the ImageView is inside the Activity.

By the way, I would move your Glide usage in onViewCreated() since onActivityCreated() is going to be deprecated soon (https://developer.android.com/jetpack/androidx/releases/fragment#1.3.0-alpha02).

Giorgio Antonioli
  • 15,771
  • 10
  • 45
  • 70
18

They are totally different things and there is not a single similarity except word activity in them.

getActivity() (or activity in case of Kotlin) is the method to access the activity that created the current fragment. It can be null so you need to check for nullability inside your code.

requireActivity() a method that returns the non-null activity instance to fragment or throws an exception.

If you are 100% sure that in your fragment's lifecycle, activity is not null, use requireActivity() as it needs no !! notation inside code, otherwise put it inside try-catch block to avoid NullPointerException.

onActivityCreated() is a lifecycle method that is called when a fragment's parent activity has been created.

.

Arrowsome
  • 2,649
  • 3
  • 10
  • 35
1

The accepted answer is good but I think it's a little mistake A correction here getActivity() does not throw any exception. It just returns null. I have covered it in detail here.

  1. The only difference is requireActivity throw an IllegalStateException if the Activity is null. but getActivity return null when that Fragment is not attached to the Activity. requireActivity() returned exception and its message. Certainly, requireActivity() throws a more explicit exception.