Fragmentieren oder nicht fragmentieren - Verschachtelte Fragmente gegen Aktivitäten. Warum sollte ich mehr als eine Aktivität verwenden?

70

Es gibt viele Diskussionen darüber, ob Sie Activitiesoder verwenden sollten Fragments. Zum Beispiel:

Die meisten Diskussionen, die ich fand, wurden vor Android 4.2 veröffentlicht.
Mit Android 4.2 hat Google verschachtelte Fragmente erfunden .

Daher sehe ich eigentlich keinen Grund mehr, mehr als einen zu verwenden Activity.

In der FragmentsAnfangsphase sollten sie in Apps verwendet werden, um Tablets und Smartphones gleichzeitig auf komfortable Weise zu unterstützen.

So haben Sie beispielsweise eine, ListViewdie Viewbeim Klicken auf ein Element ein Detail öffnen kann . Auf einem Smartphone würden wir das ersetzen ListViewund Viewstattdessen das Detail anzeigen. Während ein Tablet anstelle des Ersetzens der Liste durch die Detailansicht beide Viewsgleichzeitig anzeigen kann .


Jetzt mit verschachtelt Fragmentsgibt es viele andere Möglichkeiten. Wenn Sie eine einzelne verwenden möchten Activity, können Sie allgemeine Informationen in der speichern Activityund jeder Fragmenthat Zugriff darauf.

Außerdem könnten Fragmentsdiejenigen Fragments, die verschachtelt haben , auch Informationen für ihre Kinder speichernFragments .

Mit Fragmentskann ich das einfach wiederverwenden Views, ich kann mehrere Fragmentgleichzeitig anzeigen und ich kann einfach einen Dialog aus einem bilden Fragment. Dies alles würde mich wahrscheinlich nicht mehr als nur einige Aktionen zum Kopieren und Einfügen erfordern.

Wenn ich Activitiesstattdessen benutze, muss ich ernsthaft viel ändern, um dies zu erreichen.


Ich habe kürzlich eine Anwendung implementiert, in der ich leicht zwei verwenden kann Fragment-ViewPager, um Dinge wirklich schön und dynamisch zu machen (eine Art: Informationen von heute - Informationen von gestern). Meiner Meinung nach Fragmentsmachen Sie unser Leben viel einfacher :)


Fragen:

  • Warum sollte ich mehr als eine verwenden Activity?

Könnten Sie ein gutes Beispiel nennen, in dem die Verwendung von mehreren Activitiessinnvoller ist als die Verwendung Fragments?

  • Gibt es gute Beispiele, bei denen Sie keine andere Wahl haben, als sie zu verwenden Activities?

Ich denke, die meisten größeren Frameworks wie Maps , YouTube und Co unterstützen bereits Fragments. Wir müssen uns also nicht darauf verlassen Activities. Auch ist es ganz einfach zu bewältigen NavigationBar, TabHosts, ViewPager, ActionBarfalls Sie verwenden Fragments.


Von Udacity:

Warum nicht immer eine Aktivität mit vielen Fragmenten erstellen?

  1. Erhöhte Komplexität
  2. Härtere Absichtsbehandlung
  3. Schwer zu lesen, zu warten und zu testen
  4. Gefahr einer engen Kupplung
  5. Sicherheitsbedenken
Frame91
quelle
2
Ich habe nie daran gedacht, nur eine Aktivität zu verwenden. Die Android-Architektur legt nahe, dass die Anwendung aus Aktivitäten und die Aktivität aus Fragmenten besteht. Ich habe mich also daran gehalten. Ich freue mich auf einige interessante Antworten.
Gustek
1
Hey, ich hoffe, einige Experten werden diese Frage beantworten :) Wie gesagt, ich habe gerade angefangen, Fragmente anstelle von Aktivitäten zu verwenden und konnte noch keine Nachteile feststellen. In der letzten Woche sagte ein Kunde, dass er ein Popup anstelle einer zusätzlichen Ansicht haben möchte. Er war wirklich überrascht, als ich ihm sagte, dass ich nur zwei Codezeilen ändern muss :).
Frame91
5
Sie gehen davon aus, dass verschachtelte Fragmente gut implementiert sind. Ich habe mehr als genug Tweets und andere Kommentare von Experten und Nicht-Experten gesehen, um verschachtelte Fragmente in den Eimer "Im Notfall" zu legen.
CommonsWare
2
Aber warum sollte ich jemals ernsthaft mehr als eine Aktivität verwenden? Was für Vorteile bekomme ich daraus? Ich sehe nur einen großen Nachteil: Ich kann nur eine Aktivität gleichzeitig verwenden. Gibt es Leistungsprobleme bei der Verwendung nur von Fragmenten? Und Sie können Aktivitäten eindeutig auch falsch implementieren;)
Frame91
2
Mein Android-Buch proklamiert die Methodik "AUF!" -> Verwenden Sie immer Fragmente! Die Autoren geben hauptsächlich die Vorteile an, dass Fragmente Ressourcen sparen und das Hinzufügen von Änderungen zu einem späten Zeitpunkt in der Entwicklung einer App erleichtern.
Bofredo

Antworten:

95

Zunächst einmal stimme ich Ihnen zu, dass es möglich ist, eine große Anwendung mit nur einer Aktivität und verschachtelten Fragmenten zu schreiben. Das macht Spaß mit Software - Sie können dieselbe Funktionalität mit verschiedenen Ansätzen erreichen. Für mich hängt die Entscheidung, mehrere Aktivitäten zu verwenden, von meinen persönlichen Vorlieben hinsichtlich Kapselung, Wiederverwendbarkeit und Testbarkeit ab.

Wenn ich ein Widget habe, das in anderen Anwendungen wiederverwendet werden kann, mache ich es zu einem Fragment. Meine App verfügt beispielsweise über die Schaltfläche "Mit Server synchronisieren" und ich habe ein benutzerdefiniertes Fragment erstellt, das Fortschrittsbalken verwendet, um den Synchronisierungsprozess visuell anzuzeigen. Es ist leicht vorstellbar, dass eine andere Anwendung dieses Widget verwenden kann. Deshalb habe ich es als Fragment entwickelt.

Wenn ich Aufgaben in meiner App wechsle, sodass die neue Aufgabe konzeptionell unabhängig von der vorherigen Aufgabe ist, verwende ich eine neue Aktivität. Auf der ersten Seite meiner App werden Sie beispielsweise aufgefordert, einen Benutzer auszuwählen. Sobald Sie auf einen Benutzer geklickt haben, sende ich Sie zum Hauptmenü für diesen Benutzer. Dieses Hauptmenü für den Benutzer wird in einer neuen Aktivität angezeigt.

Stellen wir uns nun eine große, komplexe App und ein Entwicklerteam vor, das mit der Entwicklung dieser App beauftragt ist. Wenn die App in separate Aktivitäten unterteilt werden kann, ist es konzeptionell sehr einfach, die Aufgaben aufzuteilen. Jede Aktivität ist eine eigene Sandbox, sodass die parallele Entwicklung einfach und einheitlich testbar ist. Wenn es gemeinsame Bedürfnisse gibt, sollte das Team weiterhin Fragmente entwickeln und diese natürlich wiederverwenden. Ich sollte hinzufügen, dass die Wiederverwendung von Code in der Softwareentwicklung nicht oft genug vorkommt, aber wenn es richtig gemacht wird, sollte es viele wiederverwendbare Fragmente geben.

Angenommen, es ist Zeit, die App zu testen. Ihr Testteam kann jede Aktivität als eigene Black Box behandeln. Dies ist einfacher zu testen als eine einzelne große App, die auf einer einzelnen Aktivität und Tonnen verschachtelter Fragmente basiert. Dies ist besonders wichtig, wenn ein Fehler vorliegt. Wenn ein Fehler vorliegt, der nicht offensichtlich ist, weiß ich zumindest, dass der Umfang des Fehlers auf eine einzelne Aktivität von vielen beschränkt ist.

Zusammenfassend kann ich davon ausgehen, dass Sie Ihre App als Einzelperson entwickeln und Ihre Entwicklungsentscheidungen daher niemanden betreffen. Ihre Perspektiven würden sich wahrscheinlich ändern, wenn Sie eine App mit einem größeren Team entwickeln würden, und ich hoffe, dass meine Antwort in diesem Licht sehr sinnvoll ist.

Steven
quelle
2
Vielen Dank. Es ist schön, geschätzt zu werden!
Steven
1
Ich habe dir das Kopfgeld gegeben, weil es tmw abgelaufen wäre ... Aber ich höre immer noch gerne weitere Vor- und Nachteile für Fragmente / Aktivitäten;)
Frame91
1
Hier ist die Sache, Fragmente werden viel schneller geladen als das Starten neuer Aktivitäten!
Theblang
2
Ich bin der Meinung, dass jemand, der Probleme beim Testen von Fragmenten hat, sein Testframework verbessern oder seinen Code umgestalten muss. Aus meiner Sicht ist das Fragment ein Speicher für Daten und die Handhabung der Benutzeroberfläche. Die Geschäftslogik, der Datenbankzugriff und die API-Aufrufe sollten in (leicht testbaren) Serviceklassen vorliegen.
Anthropischer Android
2
Ja, das ist richtig. Wenn ein Fragment Geschäftslogik enthält, ist es unwahrscheinlich, dass es in anderen Kontexten wiederverwendet werden kann, sodass es gegen den beabsichtigten Zweck von Fragmenten verstößt. Ein erfahrener Entwickler sollte in der Lage sein, zwischen UI-Klassen wie Fragmenten und Serviceklassen zu unterscheiden. Für einen weniger erfahrenen Entwickler ist es verwirrend, die Notwendigkeit zu verstehen, die Logik durch das Erstellen von Serviceklassen zu entkoppeln, die vom Android-Framework nicht explizit benötigt werden.
Steven
2

Du hast recht. Man könnte viel allein mit Fragmenten machen. Entsprechend der Aktivitätsklasse ist eine Aktivität jedoch eine einzelne, fokussierte Sache, die der Benutzer ausführen kann. Ich neige immer dazu, meine Bewerbung in Aktivitäten auf höchster Ebene und darüber hinaus in Fragmente zu unterteilen.

In diesem Fall sind beispielsweise mehrere Aktivitäten sinnvoll. Unsere Anwendungen verfügen über eine bestimmte Funktionalität, die erweitert werden kann, wenn sich der Benutzer anmeldet. Der Benutzer kann diese eingeschränkte Funktionalität jedoch vor der Anmeldung weiterhin verwenden. Sie können beispielsweise keine Kommentare zu Elementen abgeben, es sei denn, Sie sind angemeldet MainActivity zeigt möglicherweise die gesamte Funktionalität. Wenn der Benutzer einen Kommentar abgeben möchte, bitten wir ihn, sich anzumelden, indem er seine Anfrage speichert und eine Aktivität LoginActivity startet, die die Anmeldung / Registrierung übernimmt und das richtige Ergebnis festlegt, wenn er fertig ist. In unserem aufrufenden Fragment oder unserer Aktivität prüfen wir, ob das Ergebnis LOGIN_SUCCESS ist oder ob der Benutzer derzeit angemeldet ist, und bedienen die ausstehende Anforderung. Ich versuche zu sagen, dass der Aktionsfluss von Login eine separate Aktivität sein sollte. Andernfalls wäre die Handhabung wahrscheinlich durcheinander. Auf diese Weise, Jede Aktion, für die eine Anmeldung erforderlich ist, kann startActivityForResult (LOGIN) aufrufen und sich selbst als ausstehende Aktion speichern. Nach dem Setzen des Ergebnisses konnten wir dann die Behandlung im super.onActivityResult implementieren. Dies ist natürlich alles theoretisch, man könnte Login problemlos in einem Fragment implementieren. Der Code wird jedoch definitiv als FUed angezeigt.

Eine andere Situation, in der Sie eine Aktivität benötigen, besteht darin, dass Ihre Aktivität einen exportierten Dienst bereitstellt. Angenommen, Sie sind Entwickler eines "Datei-Uploaders" und erhalten die Absicht, Dateien hochzuladen. In diesem Fall ist es sehr praktisch, eine Aktivität zu erstellen, die Anforderungen zum Hochladen einer Datei verarbeiten kann.

Mit den aktuellen Updates umfassen die Funktionen von Fragments jedoch die meisten Funktionen von Android-Apps und können daher allein mit einer einzelnen Host-Aktivität verwendet werden, um die Anforderungen einer App zu erfüllen.

Ihr gesamter "einzelner Aktivitätshost" mit Daten dort ist jedoch eher schwach verteidigt. Aktivitäten und eng Fragmente haben den gesamten Lebenszyklus, der die Instanz zum Speichern / Wiederherstellen über Bundles umfasst. Eine einzelne Wirtsaktivität kann lange dauern und mehrere Fragmente enthalten, die in einem einzigen Leben ihrer Aktivität möglicherweise mehrmals recycelt werden. Es ist daher sehr wahrscheinlich, dass eine Aktivität, die alle diese Instanzen im Laufe der Zeit hält, ihr Ressourcenbudget überschreitet. Es liegt in der Verantwortung des Entwicklers, Daten in einem gemeinsam genutzten Kontext zu halten, wenn sie tatsächlich von mehreren Objekten gemeinsam genutzt werden. Dies ist ein Nachteil dieses Ansatzes. In unserem Beispiel ist es nicht sinnvoll, dass die MainActivity ein zusätzliches Datenbyte verbraucht, da sie die Anmeldefragmente gehostet hat, wenn sie geschlafen und bei Bedarf ihren Speicher freigegeben haben könnte.

Am Ende kann ein guter Programmierer die gleiche Aufgabe ebenfalls erledigen.

Sherif elKhatib
quelle
tolles Beispiel mit der Protokollierung! Wenn wir stattdessen ein Fragment verwenden würden, könnten wir leicht einen FragmentDialog für die Anmeldung implementieren, damit der Benutzer die Aktivität nicht wechseln muss und an der Site bleiben kann, an der er weitere Berechtigungen benötigt. Meiner Meinung nach würde dies einen besseren Workflow bieten, selbst wenn es, wie Sie sagten, wahrscheinlich zu einem völlig durcheinandergebrachten Code führen würde (Es gibt auch Möglichkeiten, mit diesem Fall umzugehen, ohne den Code durcheinander zu bringen. ZB alle Fragmente über eine Schnittstelle "UserPermissionInterface" implementieren zu lassen "mit einer Methode wie Login oder Logout, die wir aus der Aktivität heraus
aufrufen
Ich bin neugierig, haben Sie eine Navigationsschublade implementiert? Und wenn ja, wie haben Sie mit mehreren Aktivitäten umgegangen, um keinen doppelten Code zu schreiben?
Theblang
@mattblang Eigentlich habe ich nie eine Navigationsschublade mit Aktivitäten implementiert: Ich finde das komisch. Ich verstehe deinen Standpunkt.
Sherif elKhatib
Ich habe eine konsistente Navigationsleiste mit Aktivitäten implementiert, indem ich einfach eine Basisklasse verwendet habe, die alle Aktivitäten, für die sie erforderlich sind, gemeinsam nutzen. Ich kann mich nicht erinnern, auf ernsthafte Probleme gestoßen zu sein.
Nestor Ledon
2

Du hast vollkommen Recht!

Warum sollte ich mehr als eine Aktivität verwenden?

Können Sie ein gutes Beispiel nennen, in dem die Verwendung mehrerer Aktivitäten sinnvoller ist als die Verwendung von Fragmenten?

Gibt es gute Beispiele, bei denen Sie keine andere Wahl haben, als Aktivitäten zu verwenden?

Ich denke, die meisten größeren Frameworks wie Maps, YouTube und Co unterstützen bereits Fragmente. Wir müssen uns also nicht auf Aktivitäten verlassen. Es ist auch recht einfach, mit NavigationBar, TabHosts, ViewPager und ActionBar umzugehen, falls Sie Fragmente verwenden.

Die Verwendung von Fragmenten ist nicht gut, um die Daten auf die Benutzeroberfläche zu übertragen, insbesondere in diesem Fall

  • ConnectionTimeOut (oder wenig Internet), da die Initialisierung der Daten viel Zeit in Anspruch nahm. Daher ist es manchmal besser, jede Aktivität zum Aufblasen weniger Daten zu verwenden als jedes Fragment.

  • Oder um die Methode onActivityResult flexibler zu verwenden, ist die Verwendung von Aktivität auch besser als. Ex. Sie können FileDialogChooser in Ihrer Anwendung aufrufen .

Das sind einige Fälle,

Vielen Dank,

Huy Tower
quelle
1

Für Ihre Fragen kann ich nur sagen, dass Sie manchmal mit einer komplexen Benutzererfahrung oder einer komplexen App, die eine andere Hardwarekomponente verwenden muss, Aktivität anstelle von Fragment verwenden müssen.

Wenn Sie beispielsweise eine App mit einem Formular erstellen müssen, das einen Schritt zum Aufnehmen eines Fotos enthält, und dieses Foto dann für eine Arbeitsspeicheraufgabe (z. B. Gesichtserkennung) verwenden, die Speicher verwendet, müssen Sie diese Aufgabe von der Hauptaufgabe trennen Aufgabenaktivität und personalisieren Sie die Berechtigung für das Manifest, mehr Speicher nur für diese Aktivität zu verwenden.

Ein weiteres Beispiel ist, wenn Sie eine schwache Speicheraktivität verwenden möchten (im Manifest können Sie Eigenschaften festlegen, mit denen der Aktivitätsstapel gelöscht und der Garbage Collector gezwungen wird, den Speicher nach Abschluss der Aktivität zu bereinigen).

Die wahrscheinlichste Situation, die mehr Aktivität und Fragmentierung erfordert, ist die Benutzererfahrung der App. Wenn Sie eine benutzerdefinierte Schublade benötigen, die ein Menü enthält und jedes Fragment des Menüs eine Listenansicht enthält und jede Listenansicht detailliert sein muss. Sie können viele Tricks ausführen, um die richtige Schublade auszublenden und Animationen zu erstellen, um vom Fragment zum Detail zu gelangen. Der beste und einfachste Weg besteht jedoch darin, eine neue Aktivität für das Detail zu erstellen und diese mit einer vom Haupt- oder Lebenszyklus getrennten Logik zu verwalten Aktivität mit der Schublade. Ich habe diese Auswahl in zwei meiner Apps getroffen:

iMeal - https://play.google.com/store/apps/details?id=it.fullsix.chiccopappe

GGRugby - https://play.google.com/store/apps/details?id=it.f6.template

In dieser App befindet sich die Schublade in der Hauptfragmentaktivität. Jedes Menü ändert das Inhaltsfragment. Die Listenansicht im Inhaltsfragment ändert den Aktivitätskontext absichtlich und wechselt in eine andere Aktivität.

Schließlich gibt es eine Situation, in der Sie meiner Meinung nach mit mehr als einer einzigen fragmentActivity arbeiten sollten ... aber dies ist mein Arbeitsmuster. Wahrscheinlich können Sie einen Trick / Weg oder einen Bereich finden, um etwas nur mit einer Aktivität und einem Fragment zu tun.

phemt.latd
quelle
Bitte klären Sie die Bedeutung von "am besten". Es könnte sehr wohl der einfachste Weg sein, aber ich kann nichts finden (wie den Speicherverbrauch, über den Sie sprechen), das diese Art der Trennung von Liste und Detail in den von Ihnen verknüpften Anwendungen rechtfertigen könnte.
Giulio Piancastelli
Die Anwendung, die ich aufgelistet habe, ist für den Fall User Expreience. Die App, die viel Speicher benötigt, befindet sich nicht im Store, sondern ist auf Ad-hoc-Hardware installiert, die zum Erstellen einer PhotoBox verwendet wird, die ich hier nicht veröffentlichen kann. Ich denke einfach, dass eine App mit einem gewissen Umfang eine Aktivität haben muss, die auf Manifest mit allen Attributen personalisiert werden kann, die Sie hier finden können: developer.android.com/guide/topics/manifest/…
phemt.latd
0

Ich weiß, dass ich dafür zu spät bin, aber Square hat eine Meinung zu Fragmenten. Hier ist der Kern des Artikels:

Fragmente: Lehren gezogen

Trotz ihrer Nachteile haben uns Fragmente unschätzbare Lektionen beigebracht, die wir jetzt beim Schreiben von Apps erneut anwenden können:

  • Einzelaktivitätsschnittstelle: Es ist nicht erforderlich, eine Aktivität für jeden Bildschirm zu verwenden. Wir können unsere App in entkoppelte Widgets aufteilen und diese nach Belieben zusammenstellen. Dies erleichtert die Animation und den Lebenszyklus. Wir können unsere Widgets in Ansichtscode und Controller-Code aufteilen.
  • Der Backstack ist kein aktivitätsspezifischer Begriff. Sie können einen Backstack innerhalb einer Aktivität implementieren.
  • Es sind keine neuen APIs erforderlich. Alles, was wir brauchten, war von Anfang an da: Aktivitäten, Ansichten und Layout-Inflater.

Sie müssen nicht mehr als eine Aktivität verwenden und Sie müssen keine Fragmente verwenden. Sie können einfach benutzerdefinierte Ansichten mit ihren Präsentatoren verwenden.

Sie können es hier lesen: https://corner.squareup.com/2014/10/advocating-against-android-fragments.html .

Die Mörtelbibliothek von Square finden Sie auch hier: https://github.com/square/mortar

Pinguin-Blues
quelle