Я знаю, что добавление транзакции фрагмента к backstack
и затем перемещение от этого фрагмента к другому фрагменту, reference of the previous fragment's view is still available
, и она уничтожается только при нажатии кнопки «Назад». И чтобы избежать этого, I have set the view to null in onDestroyView
, но проблема в том, leakcanary still shows view is not null and the view reference is still available
, тогда как запись в представлении говорит, что он нулевой.
Почему это так? Также, пожалуйста, исправьте меня, если я ошибаюсь или что-то упустил.
Класс фрагмента -
private var mView: View? = null
private lateinit var btnSignUp: Button
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mView = inflater.inflate(R.layout.fragment_login, container, false)
return mView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnSignUp = view.findViewById(R.id.btnSignUp)
btnSignUp.setOnClickListener {
// calling function changeFragment()
changeFragment(SignUpFragment(), FragmentsTag.SIGNUP_FRAGMENT)
}
}
override fun onDestroyView() {
super.onDestroyView()
mView=null
}
Журналы LeakCanary Analysis -
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
43817 bytes retained by leaking objects
Signature: 6e77557c8a679dd41391c1c5badaac98217366ad
┬───
│ GC Root: System class
│
├─ leakcanary.internal.InternalLeakCanary class
│ Leaking: NO (MainActivity↓ is not leaking and a class is never leaking)
│ ↓ static InternalLeakCanary.resumedActivity
├─ com.example.foodrunner.activities.MainActivity instance
│ Leaking: NO (LoginFragment↓ is not leaking and Activity#mDestroyed is false)
│ ↓ MainActivity.mFragments
├─ androidx.fragment.app.FragmentController instance
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ FragmentController.mHost
├─ androidx.fragment.app.FragmentActivity$HostCallbacks instance
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ FragmentActivity$HostCallbacks.mFragmentManager
├─ androidx.fragment.app.FragmentManagerImpl instance
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ FragmentManagerImpl.mActive
├─ java.util.HashMap instance
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ HashMap.table
├─ java.util.HashMap$HashMapEntry[] array
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ HashMap$HashMapEntry[].[0]
├─ java.util.HashMap$HashMapEntry instance
│ Leaking: NO (LoginFragment↓ is not leaking)
│ ↓ HashMap$HashMapEntry.value
├─ com.example.foodrunner.fragments.LoginFragment instance
│ Leaking: NO (Fragment#mFragmentManager is not null)
│ Fragment.mTag=Login Fragment
│ ↓ LoginFragment.btnLogin
│ ~~~~~~~~
├─ com.google.android.material.button.MaterialButton instance
│ Leaking: YES (View detached and has parent)
│ mContext instance of com.example.foodrunner.activities.MainActivity with mDestroyed = false
│ View#mParent is set
│ View#mAttachInfo is null (view detached)
│ View.mID = R.id.btnLogin
│ View.mWindowAttachCount = 1
│ ↓ MaterialButton.mParent
╰→ androidx.constraintlayout.widget.ConstraintLayout instance
Leaking: YES (ObjectWatcher was watching this because com.example.foodrunner.fragments.LoginFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
key = b72a82a6-b9dd-46c6-afb2-0ea6c7025001
watchDurationMillis = 9582
retainedDurationMillis = 4582
key = 0554b63a-c700-4c86-a451-b0daae06607a
watchDurationMillis = 9581
retainedDurationMillis = 4580
mContext instance of com.example.foodrunner.activities.MainActivity with mDestroyed = false
View#mParent is null
View#mAttachInfo is null (view detached)
View.mWindowAttachCount = 1
====================================