Proč ne používat lateinit modifikátor v Andrioid Fragment dat-závazné?

0

Otázka

V android dokumentaci máme příklad datové vazby bez lateinit:

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

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

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Proč nevyužíváme lateinit, jako používáme v činnosti:

private lateinit var binding: ResultProfileBinding? = null

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

Mám podezření, že má něco s problém nevracení paměti. Můžete mi to vysvětlit?

android data-binding fragment kotlin
2021-11-22 12:32:29
3

Nejlepší odpověď

2

Našel jsem vysvětlení zde.

Úryvek z vysvětlení:

Jak úniky se dějí ve fragmentech? Za prvé, musíme začít tím, že přezkoumání důležité nuance fragmentů. Mají dva různé životní cykly:

  • Je to vlastní životní cyklus (onCreate a onDestroy)
  • To je pohled lifecycle (onCreateView a onDestroyView)

Má dva životní cykly pro jednoho obrazovka může být problematické. Jsou vytvořeny a zlikvidováno v různých časy, například při uvedení fragmentu na zádech-stack. Konkrétně, drží na názory po onDestroyView nazývá se úniku. To se stane, když fragment je na zadní straně zásobníku, a i když jeho cílem je zničen, fragment sám o sobě není. Odpadky kolektor je schopen vymazat odkaz na tyto názory.

A jeden úryvek z této Přetečení Zásobníku odpověď:

Musíte null odkazy na názory v onDestroyViewjako to je znamení, že výhled je již používán Fragment systému, a to může být bezpečně do koše, kdyby to nebylo pro vaše pokračoval odkazem na View.

2021-11-22 13:35:18
0

binding fragmenty by mohly vést k nevracení paměti, pokud nejsou nastaveny na hodnotu null v onDestroyView. To je důvod, proč jsme si stanovili _binding k null v onDestroyView

Zatímco na použití lateinitnemůžeme přiřadit lateinit nemovitosti do null. Takže, pokud budeme používat lateinit binding nebudeme moci nastavit na hodnotu null v onDestroyView a to by vedlo k memory leak. To je důvod, proč android dokumentace doporučuje používat nullable proměnnou.

V případě activities nepotřebujeme přiřadit binding k null jako oni nemají vést k nevracení paměti, a můžeme použít lateinit ubytování pro binding.

2021-11-22 12:44:39

Ale proč, můžete to vysvětlit na příkladu (scénář). Tuto odpověď lze nalézt na internetu.
MatejC

Všechno, co jste řekl, je stejné jako to, co dokumentace tvrdí. Můžete uvést jeden scénář, kdy nevracení paměti může dojít? @praveen
matej-m

Fragmenty přežít své názory, pokud názory jsou zničeny ani pak by to mohlo držet, že závazné referenční.
Praveen

To není tradiční definice nevracení paměti. Je to spíš jako dočasný únik paměti, kde Fragment instance je zavěšení na odkazy na zastaralé názory, že OS chce vydat, protože Fragment je na backstack.
Tenfour04
0

Podívejte se na tento příklad

// here a firestore database uses callback to be executed when the document recieved 
db.collection("cities").document("SF").get()
        .addOnSuccessListener { document ->
            if (document != null) {
                binding.textView.text = document.data.toString()
            } else {
                Log.d(TAG, "No such document")
            }
        }

pokud uživatel otevřel fragment a zavřela, než se dokument dostal (to znamená, fragment již nelze použít, a měla by jasně všechno je proměnné podle garbage collector je-li proměnná je null nebo již nepoužívá)

Nyní pojďme diskutovat o tom, co scénář s lateinit

private lateinit var binding: ResultProfileBinding

garáže sběratel bude, není jasné binding jak to ještě použity v callback a fragment zůstane v paměti, které vedou úžasná paměť úniku, pak však zpětné volání provedeny a nastavit text, který uživatel nebude vědět o tom, protože on opustil fragment

Představte si, pokud uživatel vybral tento scénář se několikrát !!

Takže to, co o možnou hodnotou null závazné ?

private var _binding: ResultProfileBinding? = null
private val binding get() = _binding!!

ty nastavení na null v onDestroyView takže binding a fragment může být uvolněna (Žádné úniky Paměti)

ALE je to, co se stane, když callback popraven?

dostanete NullPointerException takže být vědomi, že

a co kolikrát uživatel otevřít fragment a uzavřen bude do koše

dejte si zkuste s tímto kódem, můžete použít Android Studio Profiler sledovat paměti přístroje a/nebo leakCanary , aby se informovat o aplikaci úniky paměti

2021-11-22 12:41:43

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................