Ich bin erfahren genug, um Konfigurationsänderungen zu kennen. Ich weiß, wie man den Instanzzustand eines View
, Activity
, Fragment
oder was auch immer speichert und wiederherstellt, und ich weiß, dass wir uns darauf verlassen sollten, anstatt einfach Objekte statisch zu machen.Statisches Muster zum Zurückhalten von Objekten durch Konfigurationsänderungen
Diese Frage ist über static
Ness eines Feldes. In "reinem Java" dient die Deklaration eines Objekts als static
dazu, dass es unter Instanzen geteilt wird. In dem Android-System, ein static
Feld zu deklarieren ist auch eine schnelle Möglichkeit, es überleben Konfigurationsänderungen, wenn unsere Instanz neu erstellt und seine Felder sind gelöscht.
Beispiel:
public class FooFragment extends Fragment {
private static Object sObject;
public void onViewCreated(View view, Bundle savedInstanceState) {
if (savedInstanceState == null) {
sObject = new Object();
sObject.toString();
} else {
sObject.toString();
}
}
}
In diesem Fall kann sObject
initialisiert werden, wenn das Fragment erstellt und nur abgerufen, wenn das Fragment neu erstellt wird. Probleme treten auf, wenn unsere Klasse nicht selbst statisch ist, als Basisklasse konzipiert ist oder eine Klasse abstract
ist.
public abstract class BaseFragment extends Fragment {
protected static Object sObject;
}
public class FooFragment extends BaseFragment {
public void onViewCreated(View view, Bundle savedInstanceState) {
if (savedInstanceState == null) {
sObject = new Object();
sObject.toString();
} else {
sObject.toString();
}
}
}
public class BarFragment extends BaseFragment {
public void onViewCreated(View view, Bundle savedInstanceState) {
if (savedInstanceState == null) {
sObject = new Object();
sObject.toString();
} else {
sObject.toString();
}
}
}
Nun sind beide FooFragment
und BarFragment
wird zugreifen (und impredictably verwenden), um die gleiche Instanz von sObject
. Das ist der Punkt der Statik, aber nicht das, was wir wollen. Wir wollen FooFragment
und haben ihre eigenen sObject; Wir wollen nur, dass es Konfigurationsänderungen und plattformgesteuerte Erholung überlebt.
Frage
Wie kann ich für dieses Ziel die Basisklasse entwerfen?
Das ist, was ich dachte, aber ich bin sicher, es gibt etwas Besseres.
public abstract class BaseFragment extends Fragment {
private static HashMap<String, Object> sObjects;
public void onViewCreated(View view, Bundle savedInstanceState) {
if (savedInstanceState == null) {
Object o = new Object();
sObjects.put(getClass().getName(), o);
}
}
protected final Object getObject() {
return sObjects.get(getClass().getName());
}
}
Grundsätzlich halte ich eine statische Karte, Indexierung von Kind Klassenname.
"ein statisches Feld zu deklarieren ist auch ein schneller Weg, um Konfigurationsänderungen zu überleben" - wenn Sie eine Stack Overflow Frage nach der Technik stellen müssen, ist es nicht mehr "ein schneller Weg", IMHO. Ihr Ansatz riskiert Speicherlecks, und es ist unklar, was Sie gewinnen im Vergleich zur Verwendung eines beibehaltenen Fragments (oder des gespeicherten Instanzzustands "Bundle", für Dinge, die dort hineingehen können). – CommonsWare
@CommonsWare Nun, ich habe meine Lösung gepostet, ich würde gerne wissen, ob es etwas aus der Sicht des Designs besser ist. Mein Objekt kann nicht gebündelt werden, und setRetainInstance() ist eine (meiner Meinung nach und in meinem Fall) schlechte Lösung für BaseFragments, ist aber keine Lösung für BaseViews. – natario
Ich denke, ich verbringe etwa 60% meiner Entwicklungszeit damit, Zustandsrestaurationen auf "Plattform" -Weise zu konfigurieren, also weiß ich, wovon ich rede. Ich möchte diese statische Strategie für ein bestimmtes Objekt verwenden, das nicht auf standardmäßige Weise behandelt werden kann. – natario