Willkommen bei Now in Android, Ihrem ständigen Leitfaden für Neues und Wichtiges in der Welt der Android-Entwicklung.
Android Studio Bumblebee (2021.1.1) ist jetzt stabil. Wir haben es seitdem gepatcht, um einige Startprobleme zu beheben – also aktualisieren Sie es unbedingt! Verbessert die Funktionalität in einem typischen Programmierer-Workflow: Entwicklung und Implementierung, Profilierung und Inspektion und Design.
Zu den bemerkenswerten Ergänzungen gehören ein einheitlicher Testlauf zwischen Android Studio und Ihrem Continuous Integration (CI)-Server, praktische Pairing-Streams zur Unterstützung von ADB über Wi-Fi, verbesserte Profiler-Tools, die Ihnen helfen, den Junk in Ihrer App zu identifizieren und zu analysieren, und neue Anzeigemöglichkeiten Animationen und UI-Interaktionen, ohne Ihre App auf dem Gerät zu installieren.
In der vierten Folge Simona Abdeckungen Proto-DataStore, zweite Implementierung. Der Unterschied besteht darin, dass Proto DataStore unterstützte typisierte Objekte verwendet Protokollpuffer um kleinere Datensätze zu speichern und gleichzeitig Typsicherheit zu bieten.
Simona hat auch eine Episode über Best Practices für DataStore erstellt, in der Sie erfahren, wie Sie synchrone Arbeit ausführen und wie Sie sie mit der Serialisierung von Kotlin- und Hilt-Datenklassen zum Laufen bringen. Dies ist der erste Teil der Best Practice! Also achte auf zukünftige Folgen 😄
Wir haben letztes Jahr angekündigt Wear Tiles-API. Um diese Java-API zu vervollständigen, freuen wir uns, dies bekannt zu geben Unterstützung für Wear OS-Kacheln hinzugefügt Die Aussicht, ein neuer Rahmen, der auf Jetpack Compose aufbaut und entwickelt wurde, um das Basteln für Oberflächen außerhalb Ihrer Android-App zu vereinfachen. Da diese Bibliothek in der Alpha-Version ist, würden wir sie gerne bekommen Ihre Rückmeldung.
Der Autoanwendungsbibliothek Version 1.2 befindet sich bereits in der Beta-Phase, sodass App-Entwickler mit der Entwicklung ihrer Navigations-, Park- und Lade-Apps für Android Automotive OS beginnen können. Jetzt können Entwickler mit dem Erstellen und Testen von Anwendungen für diese Kategorien beginnen Car OS-Emulator sowohl auf Android Automotive OS als auch auf Android Auto.
Jetzt, wo wir über Bibliotheksaktualisierungen sprechen, werfen wir einen Blick darauf, was mit AndroidX-Versionen passiert.
Navigation 2.4 läuft stabil jetzt! Sie können sehen, wie viel diese Version einführt Versionshinweise. Es wurde in Kotlin neu geschrieben, mit Zwei-Fenster-Integration, Navigationsrouten + Kotlin DSL-Verbesserungen, der ersten stabilen Version von Navigation Compose und Unterstützung für mehrere Backstacks. Damit ist die hilt-navigation-compose-Bibliothek erreicht ebenfalls eine stabile 1,0.
Schiebefenster-Erscheinungsbild 1.2 ist auch stabil und mit ein paar anderen Verbesserungenjetzt ist er sich der Überschneidung bewusst!
Automatisches bewusstes Überlappungsverhalten SlidingPaneLayout es ist möglich, weil AndroidX-Fensterbibliothek die ihre erste 1.0.0 erreichte ein stabiler Wendepunkt. Diese Bibliothek fügt Unterstützung für das Wechseln von Telefonen über die WindowInfoTracker- und FoldingFeature-API hinzu.
Der CameraX-Bibliotheken Version 1.1 hat die Beta-Phase erreicht, und von nun an werden alle CameraX-Bibliotheken auf dieselbe Versionsnummer ausgerichtet.
Das Team veröffentlichte auch eine integrierende Bibliothek Google Maps mit Jetpack Compose. Enthält Compose for Maps SDK für Android-Komponenten. Sie können mehr in lesen README-Projekt.
Kateryna Semenova schrieb über Verbesserung Anwendungsleistung mit Basisprofilen oder wie man die Startzeit um bis zu 40 % verbessert! Auch die Startzeit ist wichtig Grundprofile sind ein neuer Mechanismus zur Bereitstellung von Profilen und zur Verbesserung Ihrer Benutzererfahrung.
Wenn Sie sich für die Medien interessieren und wissen möchten, wie OboeDie leistungsstarke Audiobibliothek von Google hat die Aufnahmequalität und die Abschlussraten von Smule, einer Karaoke-Anwendung, verbessert. Sehen Sie sich diesen Artikel an!
Verwenden Sie Cork oder WorkManager im Hintergrund? Das Team aktualisiert Leitfaden zur Hintergrundarbeit um Ihnen bei der Auswahl der für Ihren Anwendungsfall am besten geeigneten Bibliothek zu helfen. Es hängt davon ab, ob der Job persistent ist oder nicht, und ob er sofort gestartet werden muss, dauerhaft ist oder verschoben werden kann.
Wenn Sie weiterarbeiten Android-TVes sollte Ihnen klar sein Best Practices für Barrierefreiheit, die vom Team erstellt wurden. Bietet Empfehlungen für native und nicht native Anwendungen. Erfahren Sie, warum Barrierefreiheit für Ihre TV-App wichtig ist und wie Sie Ihre Apps wann bewerten TalkBack verwendet wird, wie Systemuntertiteleinstellungen übernommen werden und mehr!!
Wenn es um Barrierefreiheit geht … Als nächstes in der Reihe ist Barrierefreiheit TalkBack, Google-Screenreader! In diesem Video erfahren Sie, was TalkBack ist, wie Sie es einrichten, wie Sie es durch die App navigieren und wie Sie damit die Zugänglichkeit Ihrer App verbessern können.
Es gab eine Folge Android-Entwickler hinter den Kulissen seit dem letzten Now in Android veröffentlicht. Schauen Sie sich den Link unten oder in Ihrem bevorzugten Podcast-Client an:
U Folge 182: Große Bildschirme sind eine große Sache, Clara, Florina und Daniel gesellen sich zu Ihren üblichen Gastgebern, um über große Bildschirme zu sprechen, was sie sind und was sie für App-Entwickler bedeuten. Sie erfahren auch mehr über die Ressourcen, die Ihnen zur Verfügung stehen, um hochwertige Erfahrungen auf Großbildgeräten zu erstellen: von Mustern und Richtlinien bis hin zu kanonischen Layouts und neuen APIs wie Klassen in Fenstergröße. Haftungsausschluss: Florina ist sehr aufgeregt darüber, verpassen Sie nicht das Epos Große Bildschirme! Große Bildschirme! Große Bildschirme! Einleitung!
In den nächsten Beiträgen von uns Jetpack DataStore-ReiheWir werden einige zusätzliche Konzepte behandeln, um zu verstehen, wie der DataStore mit anderen APIs kommuniziert, sodass Ihnen alles zur Verfügung steht, um ihn zu verwenden Produktionsumfeld. In diesem Beitrag konzentrieren wir uns besonders auf das Arbeiten Synchronbetrieb mit DataStore. Wir verweisen auf Einstellungen Codelabfür Codebeispiele.
In dieser Serie haben wir den DataStore erwähnt vollständig asynchrone APIdie sich aus der internen Verwendung ergeben Kotlin Korutine und Flow. Um potenzielle ANRs und Verzögerungen der Benutzeroberfläche zu verhindern, wenn schwierige I/O-Operationen auf UI-Threads ausgeführt werden, DataStore bietet keine gebrauchsfertige synchrone Unterstützung. Der DataStore speichert seinen Datensatz in einer Datei und führt alle Datenoperationen unter der Haube durch Dispatchers.IO, Sofern nicht anders angegeben, bleibt Ihr UI-Thread entsperrt. Diese API-Struktur ist eine von Hauptvorteile DataStore im Vergleich zum Vorgänger SharedPreferences und wie man den DataStore in den meisten Fällen verwendet.
Wenn Sie jedoch feststellen, dass Ihr Code erfordert, dass Sie synchron mit dem DataStore arbeiten, sei es, weil Sie von einer anderen API abhängig sind, die im Hauptthread ausgeführt wird, oder weil Ihr aktuelles Setup erfordert, dass Sie einige dauerhafte Werte für UI-Einstellungen abrufen, können Sie dies tun benutzen runBlocking() Programmierer zum Lesen von DataStore synchron. Dieser Wille blockiert den Anruf-Thread bis DataStore zurückkehrt:
Wenn Sie sich in einer Situation befinden, in der Sie diesen Ansatz verwenden müssen, verbringen Sie einige Zeit damit, herauszufinden, ob dies der Fall ist unbedingt notwendig, um den Hauptthread zu blockieren. Überlegen Sie, wie Sie die Lieferung nutzen könnten Asynchrone DataStore-Alternative oder refaktorisieren Sie Ihren aktuellen Code, um dies zu vermeiden runBlocking()zum Beispiel durch asynchrones Laden von Daten im Voraus:
Wenn dies nicht möglich ist, stellen Sie sicher, dass Sie alle potenziellen UI-Jank-Szenarien abdecken, indem Sie Fehler behandeln. Stornierungen und Fristen oder einige nette visuelle Elemente, um die Benutzererfahrung so einfach wie möglich zu machen.
Wir haben behandelt, wie es durchgeführt wird Synchronbetrieb mit DataStore. Obwohl dies kein empfohlener Ansatz für den DataStore ist, können Sie ihn verwenden, wenn Ihre aktuelle Einstellung synchrone Aufrufe erfordert .runBlocking() kombiniert mit .first() Operator.
Begleiten Sie uns für den nächsten Beitrag in der Serie, in dem wir untersuchen, wie es geht DataStore-zu-DataStore-Migration.
In den nächsten Beiträgen von uns Jetpack DataStore-ReiheWir behandeln einige zusätzliche Konzepte, um zu verstehen, wie der DataStore mit anderen APIs interagiert, sodass Sie alles zur Verfügung haben, um ihn zu verwenden Produktionsumfeld. In diesem Beitrag konzentrieren wir uns auf Kotlin-Serialisierung. Wir verweisen auf Einstellungen ich Proto Codelabs über diesen Beitrag für Codebeispiele.
In unseren vorherigen Beiträgen haben wir geschrieben, wie Einstellungen ich Proto DataStore-Ansatz zur Strukturierung und Serialisierung Ihrer persistenten Daten: Vorteile von Proto typisierte Objekte unterstützt Protokollpuffer, während Einstellungen verwendet Schlüssel/Wert-Paare wie unsere Datenanzeige, ähnlich wie SharedPreferences. Unter der Haube, Beide Implementierungen speichern Daten unter Verwendung von Protokollpuffern auf der Festplatte in einer Datei. Aber der DataStore ermöglicht es Ihnen auch, dies anzupassen und auch Datenklassen zu verwenden Kotlin-Serialisierungdir geben Art des Sicherheitsvorteils Proto DataStore, aber ohne die Notwendigkeit, Protobuffs zu verwenden. Sehen wir uns an, wie die Serialisierung standardmäßig für jeden dieser Ansätze funktioniert:
DataStore-Serialisierungsoptionen
Preferences DataStore vereinfacht die Arbeit mit Protobuffs durch Hinzufügen zusätzliche Schicht zusätzlich zu seiner geringen Proto-Implementierung. Auf diese Weise erhalten Sie es viele Vorteile der Arbeit mit DataStoreaber mit a SharedPreferences-als Mittel zur Strukturierung von Daten verwenden Schlüssel/Wert-Paare.
Wenn wir uns die Preferences API ansehen PreferencesSerializer und unser benutzerdefiniertes ProtoUserPreferencesSerializerSie werden feststellen, dass sie meistens dasselbe tun. PreferencesSerializer es hat nur einen zusätzlichen Transformationsschritt Schlüssel/Wert-Paare in Protobuffs und umgekehrt:
Implementierung von DataStore mit Kotlin-Serialisierung
Wenn Sie verwenden möchten Kotlin-Serialisierung Um Ihre Daten zu strukturieren, müssen Sie lediglich a definieren eine vollständig unveränderliche Datenklasse und einen DataStore implementieren Serializer.
DataStore verlässt sich auf equals ich hashCode die für Datenklassen automatisch generiert werden. Es werden auch Datenklassen generiert toString ich copy Funktionen, die zum Debuggen und Aktualisieren von Daten nützlich sind:
🚨 Das ist sehr wichtig Stellen Sie sicher, dass Ihre Klasse unveränderlich ist seit DataStore ist nicht mit Variablentypen kompatibel. Die Verwendung von Variablentypen mit dem DataStore führt dazu Fehler aufgrund inkonsistenter Daten und Rennbedingungen. Datenklassen Sie sind nicht unbedingt standardmäßig unveränderlichStellen Sie also sicher, dass Sie überall wave anstelle von vars verwenden:
Arrays sind variabel, also sollten sie nicht ausgesetzt werden. Auch wenn wir es nur zum Lesen verwenden List als Mitglied unserer Datenklasse ist es immer noch variabel. Stattdessen sollten Sie erwägen, es zu verwenden unveränderliche / dauerhafte Sammlungen:
Die Verwendung von Variablentypen als Mitglied Ihrer Datenklasse macht sie änderbar. Stattdessen sollten Sie dafür sorgen alles Mitglieder sind unveränderliche Typen.
Kotlin unterstützt die Serialisierungmehrere Formateeinschließlich JSON und Protokollpuffer. In diesem Beispiel fahren wir mit JSON fort.
Um Ihre Datenklasse in JSON mithilfe der Kotlin-Serialisierung zu lesen und zu schreiben, müssen Sie Ihre Datenklasse mit markieren @Serializable und überwältigen Serializer’swriteTo() ich readFrom(). Hier ein Beispiel mit UserPreferences:
⚠️ Grundstücke sind nicht sicher mit DataStore verwenden, da sich das Datenformat zwischen Android-Versionen ändern kann.
Gehen Sie die neu erstellten durch UserPreferencesSerializer im DataStore, wenn Sie es erstellen:
Das Auslesen der Daten sieht genauso aus wie bei Protobuffs:
Sie können die generierte verwenden .copy() Datenaktualisierungsfunktion:
Verwenden von DataStore mit Kotlin-Serialisierung und Datenklassen kann den Standard senken und Ihren Code vereinfachenSie müssen jedoch darauf achten, es nicht einzuführen Fehler durch Variabilität. Sie müssen lediglich Ihre Datenklasse definieren und einen Serializer implementieren.
Wir deckten ab Kotlin-Serialisierung und die notwendigen Schritte zur Verwendung Persistente DataStore-Daten strukturieren – Verwenden von vollständig unveränderlichen Datenklassen und Schreiben in JSON mit@Serializable Beachten Sie, überwältigend unsere Serializer’swriteTo() ich readFrom() und schließlich die Weiterleitung an unsere DataStore-Instanz.
Begleiten Sie uns für den nächsten Beitrag in unserer Serie, in dem wir untersuchen, wie es geht Synchronbetrieb mit DataStore.
Eine Bibliothek, die Janko in der realen Welt verfolgt
Jank (Substantiv): Schlechte Anwendungsleistung, die zu fehlenden Frames, unterbrochenen UI-Bewegungen und schlechter Benutzererfahrung führen kann. Siehe „Unzufriedene Benutzer“.
Das Debuggen der Leistung ist … schwierig. Es ist oft nicht klar, wo man anfangen soll, welche Tools zu verwenden sind, welche Probleme Benutzer haben oder wie sich diese Probleme auf realen Geräten manifestieren.
Das Android-Team hat in den letzten Jahren mehr Debugging-Tools für verschiedene Teile des Problems bereitgestellt, angefangen bei der Analyse Startleistung beim Testen bestimmte Codepfade insbesondere auf das Testen und Optimieren Anwendungsfälle zu visuelle Profiler in der IDE. All dies dient zum Testen der Entwicklungszeit, um Ihnen bei der Fehlerbehebung und Behebung von Problemen zu helfen, die Sie lokal sehen.
Inzwischen sind beide Google Play Android-Vitals ich Firebase Bieten Sie Dashboards an, in denen Entwickler sehen können, wie ihre Apps auf Benutzergeräten im Feld funktionieren.
Es ist jedoch schwierig zu wissen, wie Sie Probleme finden können, die Ihre Anwendung in realen Situationen haben kann, insbesondere Probleme, die auf Benutzergeräten auftreten, und nicht nur Situationen, die Sie auf dieser praktischen Entwicklungsmaschine sehen, die Sie bequem von Ihrem Stuhl aus verwenden. Leistungssteuerungsfelder sind hilfreich, bieten jedoch nicht unbedingt die Detailgenauigkeit, die Sie benötigen, um zu wissen, was passiert ist, wenn Ihre Benutzer Probleme hatten.
Eingeben JankStats: Die erste AndroidX-Bibliothek, die speziell für die Instrumentierung und Meldung von Leistungsproblemen Ihrer App auf Benutzergeräten entwickelt wurde.
JankStats ist eine relativ kleine API mit im Wesentlichen drei Zielen: Erfassen von Leistungsinformationen pro Frame, Ausführen Ihrer Anwendung auf Benutzergeräten (nicht nur Entwicklungsgeräten) und Aktivieren von Instrumentierung und Berichten darüber, was in Ihrer Anwendung passiert, wenn es Leistungsprobleme gibt.
Die Android-Plattform bietet bereits Möglichkeiten, Frame-Performance-Daten abzurufen. Beispielsweise können Sie FrameMetrics ab API 24 verwenden, und wir haben es in neueren Versionen hinzugefügt, um noch mehr Informationen bereitzustellen. Wenn Sie frühere Versionen verwenden, gibt es verschiedene Ansätze, um weniger genaue, aber dennoch nützliche Wetterinformationen zu erhalten.
Wenn Sie also möchten, dass Ihre eigene Frame-Dauer-Logik in allen Editionen funktioniert, müssen Sie diese verschiedenen Mechanismen in allen Versionen der API implementieren. Oder Sie können die einzigartige JankStats-API verwenden, die für Sie funktioniert … zusätzlich zu den zusätzlichen Funktionen oben (lesen Sie weiter!).
JankStats vereinfacht dies, indem es eine einzelne Bildraten-Berichts-API bereitstellt und geeignete Mechanismen intern delegiert (FrameMetrics auf API 24+ usw.). Sie müssen sich keine Gedanken darüber machen, woher diese Informationen stammen, Sie können JankStats einfach fragen, wie lange es gedauert hat, und Sie erhalten Rückrufe mit diesen Informationen.
Das Erstellen und Anhören von JankStats-Daten ist im Grunde so einfach: Sie erstellen sie, und dann lehnen Sie sich zurück (okay, Ihr Code entspannt sich) und hören zu. Hier sind Beispiele für diese Schritte aus dem JankStats-Beispiel, JankLoggingActivity:
val jankFrameListener = JankStats.OnFrameListener { frameData -> // real app would do something more interesting than log this... Log.v("JankStatsSample", frameData.toString()) }jankStats = JankStats.createAndTrack( window, Dispatchers.Default.asExecutor(), jankFrameListener, )
Im Gegensatz zu neueren Benchmarking-Bibliotheken wurde JankStats erstellt, um Ergebnisse von Benutzergeräten bereitzustellen. Es ist großartig, Fehler auf Ihrem Entwicklungscomputer zu beheben, aber es hilft nicht in Situationen, in denen Ihre Anwendung von echten Menschen in der realen Welt auf sehr unterschiedlichen Geräten und unter sehr unterschiedlichen Einschränkungen verwendet wird.
JankStats bietet eine API zum Instrumentieren Ihrer Anwendung, um die benötigten Leistungsdaten bereitzustellen, und einen Berichtsmechanismus, damit Sie diese Daten hochladen und offline analysieren können.
Schließlich (hören Sie: Das ist eine wirklich neue Sache mit dieser Bibliothek) bietet JankStats eine Möglichkeit zu verstehen, was wirklich in Ihrer App vor sich ging, als Leistungsprobleme auftraten. Die Beschwerde, die wir oft gehört haben, ist, dass vorhandene Tools, Dashboards und Ansätze Ihnen nicht genug geben Kontext für Leistungsprobleme, die Ihre Benutzer möglicherweise sehen.
Beispielsweise kann Ihnen die FrameMetrics-API (eingeführt in API 24 und intern in JankStats verwendet) mitteilen, wie lange es dauert, Frames zu zeichnen, aus denen Sie Informationen über den Ruck extrahieren können. Aber es kann Ihnen nicht sagen, was damals in Ihrer Bewerbung vor sich ging. Dieses Problem müssen Sie verstehen, wenn Sie versuchen, Ihren Code zu instrumentieren und in FrameMetrics oder andere Tools zur Leistungsmessung zu integrieren. Aber jeder hat genug zu tun, ohne dass diese Art von Infrastruktur intern aufgebaut werden muss, sodass der Ruck in der Regel ungemessen bleibt und die Performance-Probleme weiterhin bestehen.
In ähnlicher Weise kann Ihnen das Android Vitals-Dashboard mitteilen, dass Ihre App Leistungsprobleme hat, aber es kann Ihnen nicht sagen, was Ihre App tat, als diese Probleme auftraten. Es ist also schwer zu wissen, was man mit diesen Informationen anfangen soll.
JankStats präsentiert PerformanceMetricsState API, ein einfacher Satz von Methoden, mit denen Sie dem System jederzeit paarweise mitteilen können, was in Ihrer Anwendung passiert StringS. Beispielsweise möchten Sie möglicherweise aufzeichnen, wenn dies angegeben ist Activity oder Fragment aktiv sind, oder wenn a RecyclerView blättert.
Hier ist beispielsweise der Code aus dem JankStats-Beispiel, der zeigt, wie RecyclerView angewiesen wird, JankStats diese Informationen bereitzustellen:
Dieser Status kann von überall in Ihre Anwendung eingefügt werden (oder sogar aus einer anderen Bibliothek), und JankStats nimmt ihn auf, wenn Ergebnisse gemeldet werden. Auf diese Weise erfahren Sie, wenn Sie Berichte von JankStats erhalten, nicht nur, wie lange die Dinge in jedem Frame gedauert haben, sondern auch, was der Benutzer während dieses Frames getan hat, was ein beitragender Faktor sein könnte.
Hier sind einige Ressourcen, um mehr über JankStats zu erfahren:
Dokumente: Unsere Website für Entwickler hat eine neue Entwicklerleitfaden die beschreibt, wie man JankStats benutzt.
Codebeispiel: Dies Projekt enthält Beispiele, die zeigen, wie JankStats-Objekte instanziiert und überwacht werden, zusammen mit der Instrumentierung Ihrer Anwendung mit wichtigen UI-Statusinformationen:
Fehler, Fehler, Fehler: Wenn Sie irgendwelche Probleme mit der Bibliothek haben oder API-Anforderungen haben, bitte einen Fehler melden.
JankStats hat gerade seine erste Alpha-Version veröffentlicht, was bedeutet: „Wir denken, dass dies eine API und Funktionalität ist, die für 1.0 sinnvoll sind, aber bitte versuchen Sie es und lassen Sie es uns wissen.“
Es gibt andere Dinge, die wir in Zukunft gerne mit JankStats machen würden, darunter das Hinzufügen einer Art Aggregationsmechanismus oder sogar die Synchronisierung mit bestehenden Upload-Diensten. Aber wir wollten diese erste Version mit grundlegenden Installationen veröffentlichen, um zu sehen, wie Sie sie verwenden und was Sie sonst noch sehen möchten. Wir hoffen, dass es in seinem jetzigen Grundzustand nützlich sein wird; allein die Möglichkeit, Statusinformationen der Benutzeroberfläche einfach zu instrumentieren und dann aufzuzeichnen, sollte besser sein, als … diese Fähigkeit nicht zu haben.
In den nächsten Beiträgen von uns Jetpack DataStore-ReiheWir behandeln einige zusätzliche Konzepte, um zu verstehen, wie DataStore mit anderen APIs kommuniziert, damit Ihnen alles zur Verfügung steht, was Sie verwenden können Produktionsumfeld. In diesem Beitrag konzentrieren wir uns auf Einspritzabhängigkeiten sind Griff. Wir verweisen auf Datenspeicher Einstellungen ich Proto codelabs durch diesen Beitrag für Codebeispiele.
In diesen Code-Labs haben wir mit unseren DataStore-Instanzen kommuniziert Einstellungen ich ProtoBaudelegierter einmal auf der höchsten Ebene der Kotlin-Datei. Dann würden wir dieselbe Instanz in Ihrer gesamten Anwendung als verwenden Einzelling:
Wir brauchen einen Singleton für die Erstellung mehr als eine Instanz aus dem DataStore für eine bestimmte Datei kann alle DataStore-Funktionen beschädigen. In einer Produktionsumgebung würden wir jedoch normalerweise eine DataStore-Instanz per erhalten Injektionsabhängigkeit. Schauen wir uns also an, wie der DataStore mit arbeitet Griffeine Suchtinjektionsbibliothek, um uns zu helfen Standard reduzieren manuelles Abhängigkeitsmanagement. Wenn Sie mit Hilt nicht vertraut sind, empfehlen wir Ihnen, es zuerst durchzugehen Verwenden Sie Hilt in Ihrer Android-App Codelab zum Erlernen grundlegender Konzepte wie z Components, Modules und andere.
Griff platzieren
Stellen Sie zunächst sicher, dass Sie alle erforderlichen Einrichtungsschritte hinzugefügt haben, um Hilt zu aktivieren:
Alle Anwendungen, die Hilt verwenden, müssen enthalten Application Klasse mit gekennzeichnet @HiltAndroidApp zum Ausführen der Hilt-Codegenerierung, einschließlich der Basisklasse für Ihre Anwendung, die als Abhängigkeitscontainer auf Anwendungsebene dient. In unserem Fall erstellen wir eine einfache TasksApp und füge es unserem hinzu AndroidManifest.xml:
DataStore-Einstellungen einfügen
Um ein zu erhalten Einstellungen für DataStore-Instanzen Durch die Injektion müssen wir Hilt sagen, wie man es richtig herstellt. Wir gebrauchen PreferenceDataStoreFactory und füge es hinzu ua Handlaufmodul:
Wir haben diese Parameter bereits in der Serie erwähnt, aber fassen wir schnell zusammen:
corruptionHandler (optional) – aufgerufen, wenn a CorruptionException wird vom Serialisierer ausgeworfen, wenn Daten nicht deserialisiert werden können, und gibt dem DataStore Anweisungen zum Ersetzen beschädigter Daten
migrations (optional) – Liste DataMigration vorherige Daten in den DataStore zu verschieben
scope (optional) – das Ausmaß, in dem IO-Operationen und Transformationsfunktionen durchgeführt werden; in diesem Fall verwenden wir wieder gleichen Bereich wie die standardmäßige DataStore-API
produceFile – erzeugt File Objekt für Preferences DataStore basierend auf geliefert Context ich namedarin gespeichert this.applicationContext.filesDir + datastore/ Unterverzeichnisse
Jetzt, da wir ein Modul haben, das Hilt anweist, wie wir unseren DataStore erstellen, müssen wir noch ein paar Anpassungen vornehmen, damit wir erfolgreich bauen können.
Hilt kann Abhängigkeiten zu anderen Android-Klassen bereitstellen, die sie haben @AndroidEntryPoint Hinweis, zusammen mit @HiltAndroidApp Pro Application ich @HiltViewModel Pro ViewModel Klassen. Wenn Sie die Android-Klasse mit markieren @AndroidEntryPoint, dann müssen Sie auch andere Android-Klassen markieren, die davon abhängen. Wenn Sie zum Beispiel a notieren Fragmentdann müssen Sie auch alle Aktivitäten markieren, bei denen Sie es verwenden Fragment.
Das bedeutet, dass wir Folgendes hinzufügen müssen:
Wir haben keine anderen in dieser Probe komplexe Injektionen, wie benutzerdefinierte Builder, Factorys oder Schnittstellenimplementierungen. Wir können uns also auf Hilt und die Konstruktorinjektion für alle anderen Abhängigkeiten verlassen, die wir durchlaufen müssen. Wir werden verwenden @Inject ein Hinweis im Klassenkonstruktor, um Hilt anzuweisen, wie seine Instanzen bereitzustellen sind:
Lassen Sie uns es schließlich vollständig loswerden preferencesDataStore ein Delegierter von der Spitze von uns TasksActivity da wir es nicht mehr brauchen. Wir werden auch die Art und Weise ändern, wie es uns gehört viewModel ist vorgesehen TaskActivityonCreatedenn seine Abhängigkeiten werden nun eingefügt:
Proto DataStore einfügen
Proto-DataStore würde einem sehr ähnlichen Muster folgen – Sie sollten zusätzlich sicherstellen, dass a UserPreferencesSerializer und genaue Anweisungen zur Migration von SharedPreferencesauf die wir näher eingegangen sind Proto DataStore-Beitrag:
Das ist es! Sie können die App jetzt ausführen und überprüfen, ob alle Abhängigkeiten jetzt korrekt eingefügt wurden.
Wir haben die Schritte weiter abgedeckt wie man DataStore mit Hilt injiziert für ein besseres Suchtmanagement, Hilta-Setup, verwenden PreferenceDataStoreFactory in unserer DataStoreModule um Hilt anzuweisen, wie unsere DataStore-Instanz ordnungsgemäß gesichert wird, und um sie schließlich den Klassen zur Verfügung zu stellen, die dies benötigen.
Begleiten Sie uns für den nächsten Beitrag aus unserer Serie, in dem wir untersuchen, wie man es verwendet Data Warehouse mit Kotlin-Serialisierung.
Das erfahren wir in diesem Beitrag Proto-DataStoreeiner von zwei DataStore-Implementierungen. Wir werden darüber sprechen, wie erstellen, Daten lesen und schreiben und Ausnahmen behandelnum die Szenarien besser zu verstehen, die Proto zu einer guten Wahl machen.
Proto DataStore verwendet typisierte Objekte, die von unterstützt werden Protokollpufferkleinere Datensätze beim Bereitstellen zu speichern Typ Sicherheit. Dadurch entfällt die Notwendigkeit, Schlüssel/Wert-Paare zu verwenden strukturell anders von seinem SharedPreferences Vorgänger und seine zugehörige Implementierung, DataStore-Einstellungen. Doch das ist noch nicht alles – berichtet DataStore viele weitere Verbesserungen fertig SharedPreferences. Melden Sie sich schnell bei uns zurück erster Beitrag in Folge und schauen Sie sich den detaillierten Vergleich an, den wir dort gemacht haben. Wir werden uns das Folgende ansehen Proto DataStore wie nur Protowenn nicht anders angegeben.
zusammenfassen:
Bietet ein vollständig asynchrone API zum Herunterladen und Speichern von Daten mit der Kraft von Kotlin Korutina
Es bietet keine gebrauchsfertige synchrone Unterstützung – vermeidet direkt jegliche Arbeit, die den UI-Thread blockiert
Es stützt sich auf den internen Fehlersignalisierungsmechanismus von Flow, sodass Sie sicher arbeiten können Ausnahmen abfangen und verarbeiten beim Lesen oder Schreiben von Daten
Verarbeitet sicher Datenaktualisierungen in Atomare Read-Modify-Write-Operationstark zur Verfügung stellen SÄURE Garantien
Erlaubt einfache und einfache Datenmigration
Müssen vollständige Sicherheit und Ihre Daten erfordern die Arbeit mit mehr komplexe Klassen, wie Aufzählungen oder Listen? Dies ist mit nicht möglich Einstellungenalso wähle Proto stattdessen
Um Proto DataStore nutzen zu können, müssen Sie sich kennenlernen Protokollpuffer– sprachneutraler, plattformneutraler Mechanismus für Serialisierung strukturierter Daten. Es ist schneller, kleiner, einfacher und eindeutiger als XML und leichter zu lesen als andere ähnliche Datenformate.
Sie definieren ein Schema aus wie Sie Ihre Daten strukturiert haben möchten und geben Sie Optionen an, z. B. welche Sprache zum Generieren des Codes verwendet werden soll. Der Compiler generiert dann Klassen nach Ihren Vorgaben. Dadurch können Sie problemlos strukturierte Daten schreiben und lesen zu und von verschiedenen Datenströmen, Austausch zwischen verschiedenen Plattformen, Verwendung mehrerer verschiedener Sprachen, z. Kotlin.
Beispielschema einiger Daten ua .proto Datei:
So verwenden Sie den generierten Kotlin-Code zum Erstellen Ihres Datenmodells:
Etwas mehr Zeit in das Erlernen dieses neuen Serialisierungsmechanismus zu investieren, lohnt sich auf jeden Fall, denn er bringt Typsicherheit, verbesserte Lesbarkeit und allgemeine Einfachheit des Codes.
Schauen wir uns jetzt etwas Code an und lernen, wie Proto funktioniert.
Wir werden verwenden Proto-DataStore Codelab-Muster. Wenn Sie an einem praktischeren Ansatz zur Implementierung interessiert sind, empfehlen wir Ihnen wirklich, es durchzugehen Arbeiten Sie mit Proto DataStore Codelab selbstständig.
Diese Beispielanwendung zeigt eine Liste von Aufgaben an, und der Benutzer kann sie nach ihrem abgeschlossenen Status filtern oder nach Priorität und Frist sortieren. Wir möchten ihre Auswahl speichern boolean, um abgeschlossene Aufgaben anzuzeigen ia Aufzählung sortieren Proto.
Wir werden zunächst Proto-Abhängigkeiten und einige der grundlegenden Protobuff-Einstellungen zu Ihrem Modul hinzufügen build.gradle. Wenn Sie an einer fortgeschritteneren Anpassung der Protobuffs-Kompilation interessiert sind, werfen Sie einen Blick darauf Protobuf-Plugin für Gradle-Notizen:
💡 Kurzer Tipp – Wenn Sie Ihre Konstruktion minimieren möchten, fügen Sie unbedingt eine zusätzliche Regel hinzu proguard-rules.pro Datei, um zu verhindern, dass Ihre Felder gelöscht werden:
Unsere Reise mit Proto beginnt mit der Definition Ihrer Struktur persistente Daten u .proto Datei. Betrachten Sie es als lesbares Schema für dich u.a Entwurf für den Compiler. Wir werden unsere nennen user_prefs.proto und füge es hinzu app/src/main/proto Verzeichnis.
Begleitet Protobuf-SprachführerWir werden dieser Datei ein hinzufügen Nachricht für jede Datenstruktur wir wollen serialisieren und dann a spezifizieren Name ia Typ für jedes Feld in der Nachricht. Um dies einfacher zu visualisieren, schauen wir uns sowohl die Kotlin-Datenklasse als auch das entsprechende Protobuff-Schema an.
UserPreferences – Kotlin-Datenklasse:
UserPreferences – .proto planen:
Wenn Sie noch nie Protobuffs verwendet haben, interessieren Sie sich vielleicht für die ersten Zeilen des Schemas. Lassen Sie uns sie aufschlüsseln:
java_package – eine Dateioption, die angibt Paketerklärung für Ihre generierten Klassen, was dazu beiträgt, dies zu verhindern Namenskonflikte zwischen verschiedenen Projekten
java_multiple_files – eine Dateioption, die angibt, ob nur eine einzelne Datei mit verschachtelten Unterklassen werden hierfür generiert .proto (wenn auf false gesetzt) oder if getrennte Dateien wird für jeden Nachrichtentyp der obersten Ebene generiert (wenn auf wahr gesetzt); es ist standardmäßig falsch
Das Folgende ist die Definition unserer Botschaft. Eine Nachricht ist ein Aggregat, das enthält eine Reihe von typisierten Feldern. Viele einfache Standarddatentypen sind als Feldtypen verfügbar, einschließlich bool, int32, floatdoppelt i string. Sie können Ihre Nachrichten auch mit weiter strukturieren andere Nachrichtentypen als Feldtypenwie wir mit SortOrder.
Der = 1, = 2 Die Markierungen auf jedem Element identifizieren das eindeutige “Tag”, das das Feld in der Binärcodierung verwendet – wie z. B. die Sortier-ID. Wenn Ihr Nachrichtentyp verwendet wird, müssen diese Nummern nicht geändert werden.
Wenn Sie den Protokollpuffer-Compiler auf einem ausführen .proto, Der Compiler generiert Code in der von Ihnen ausgewählten Sprache. In unserem speziellen Fall führt dies beim Start des Compilers zur Generierung UserPreferences Klasse, die in Ihrer Bewerbung enthalten ist build/generated/source/proto… Verzeichnis:
💡 Schneller Tipp – Du kannst auch die neu angekündigten ausprobieren Kotlin DSL-Unterstützung für Protokollpuffer um eine idiomatischere Methode zum Erstellen Ihres Datenmodells zu verwenden.
Jetzt, wo wir haben UserPreferenceswir müssen angeben Richtlinien wie Proto sie lesen und schreiben soll. Wir tun dies über den DataStore Serializer es bestimmt das endgültige Format Ihrer Daten wann es gespeichert wird und wie man richtig darauf zugreift. Dies erfordert das Überschreiben von:
defaultValue – was zurückgegeben werden soll, wenn keine Daten vorhanden sind
writeTo – wie man die Speicheranzeige unseres Datenobjekts in ein für die Speicherung geeignetes Format umwandelt
readFrom – die Umkehrung des Obigen, wie man von einem Speicherformat in eine geeignete Speicheranzeige umwandelt
Um Ihren Code so sicher wie möglich zu machen, zu handhaben CorruptionException um unangenehme Überraschungen zu vermeiden, wenn die Datei aufgrund einer Formatbeschädigung nicht deserialisiert werden kann.
💡 Kurztipp – Wenn dein AS mal nichts finden kann UserPreferences in Verbindung gebracht, reinigen und erneuern Ihr Projekt, um mit der Generierung von Protobuff-Klassen zu beginnen.
Sie interagieren mit Proto über Instanzen DataStore<UserPreferences>. DataStore ist eine Schnittstelle, die bietet Zugriff auf dauerhafte Informationenin unserem Fall in der generierten Form UserPreferences.
Es wird empfohlen, zum Erstellen dieser Instanz einen Delegaten zu verwenden dataStore und Pass erforderlich fileName ich serializer Argumente:
fileName verwendet, um a zu erstellen File verwendet, um Daten zu speichern. Deshalb ist es so dataStore Der Delegierte ist a Kotlin-Eigenschaftserweiterung dessen Empfängertyp eine Instanz sein muss Contextweil es benötigt wird, um eine Datei über zu erstellen applicationContext.filesDir. Vermeiden Sie die Verwendung dieser Datei außerhalb von Proto, da dies die Konsistenz Ihrer Daten beeinträchtigen würde.
U dataStore Delegierten können Sie ein weiteres optionales Argument weiterleiten – corruptionHandler. Dieser Operator heißt, wenn a CorruptionException wurde vom Serialisierer ausgeworfen, als Daten können nicht deserialisiert werden. corruptionHandler würde dann Proto anweisen, wie die beschädigten Daten zu ersetzen sind:
Sie sollten nicht mehr als eine DataStore-Instanz für eine bestimmte Datei erstellen, weil es die gesamte Funktionalität des DataStore ruinieren kann. Daher können Sie ein Delegate-Konstrukt einmal auf der obersten Ebene Ihrer Kotlin-Datei hinzufügen und es in der gesamten Anwendung verwenden, um es als zu übergeben Einzelling. Wie das mit einer Suchtspritze geht, sehen wir uns in späteren Beiträgen an.
Zum Auslesen gespeicherter Daten, u UserPreferencesRepository wir belichten a Flow<UserPreferences> von userPreferencesStore.data. Dies ermöglicht ein effizientes Vorgehen der letzte erhaltene Zustand ich Sendungen bei jeder Änderung. Dies ist einer von größte Stärke von Proto – deins Flow‘s Werte kommen bereits in der generierten Form UserPreferences. Das heisst Sie müssen keine zusätzlichen Transformationen vornehmen von den gespeicherten Daten zum Kotlin-Datenklassenmodell, so wie Sie es tun würden SharedPreferences oder Preferences DataStore:
Flow wird immer entweder einen Wert ausgeben oder verwerfen Sie die Ausnahme beim Versuch, von der Festplatte zu lesen. Wir werden uns in späteren Abschnitten mit der Behandlung von Ausnahmen befassen. Der DataStore stellt außerdem sicher, dass die Arbeit immer erledigt wird Dispatchers.IO Ihr UI-Thread wird also nicht blockiert.
🚨 Erstellen Sie keine Cache-Repositories um den aktuellen Stand Ihrer Proto-Daten abzubilden. Damit erlischt die DataStore-Garantie für Datenkonsistenz. Wenn Sie eine Aufnahme Ihrer Daten ohne ein Abonnement für weitere Flow-Shows benötigen, verwenden Sie sie stattdessen userPreferencesStore.data.first():
Wir werden die Aussetzung verwenden, um Daten zu schreiben DataStore<UserPreferences>.updateData(transform: suspend (t: T) -> T) Funktion.
Lassen Sie es uns aufschlüsseln:
DataStore<UserPreferences> Schnittstelle – wird derzeit verwendet userPreferencesStore als konkrete Implementierung von Proto
transform: suspend (t: T) -> T) – ein Suspend-Block, der verwendet wird, um bestimmte Änderungen an unseren permanenten T-Typ-Daten anzuwenden
Auch hier können Sie einen Unterschied bemerken Preferences DataStore die auf den Gebrauch angewiesen ist Preferences ich MutablePreferencesähnlich Map ich MutableMapals Standarddatenanzeige.
Jetzt können wir dies nutzen, um unsere zu ändern showCompleted boolesch. Protokollpuffer vereinfachen dies ebenfallsEliminierung der Notwendigkeit einer manuellen Transformation in und aus Datenklassen:
Es gibt mehrere Schritte für die Analyse:
toBuilder() – er gewann Builder Version von uns currentPreferences die es für Änderungen „freischaltet“.
.setShowCompleted(completed) – setzt einen neuen Wert
.build() – Beendet den Update-Vorgang durch Konvertieren in UserPreferences
Die Datenaktualisierung erfolgt transaktional in einem Atomare Read-Modify-Write-Operation. Das bedeutet, dass es eine bestimmte Abfolge von Datenverarbeitungsvorgängen garantiert, während derer Daten für andere Threads gesperrt sind Konsistenz ich verhindert Rennbedingungen. Nur nach transform ich updateData Corutins erfolgreich abgeschlossen, Daten werden dauerhaft auf der Festplatte gespeichert und userPreferencesStore.data Der Fluss wird die Aktualisierung widerspiegeln.
🚨 Beachten Sie, dass dies die einzige Möglichkeit ist, den Status des DataStore zu ändern. Wartung u UserPreferences Referenz und manuelle Mutation danach transform vervollständigt ändert die permanenten Daten nicht in Proto, also sollten Sie nicht versuchen zu modifizieren UserPreferences außen transform Block.
Wenn der Schreibvorgang aus irgendeinem Grund fehlschlägt, wird die Transaktion beendet und eine Ausnahme ausgelöst.
Wenn Sie es zuvor verwendet haben SharedPreferences in Ihrer Anwendung und Sie Ihre Daten sicher an Proto übertragen möchten, können Sie verwenden SharedPreferencesMigration. Dazu braucht es Kontext, SharedPreferences Namen und Anweisungen, wie Sie Ihren eigenen umwandeln können SharedPreferences Schlüssel/Wert-Paare für UserPreferences Innerhalb migrate Parameter. Geben Sie dies weiter produceMigrations ParameterdataStore Delegierter für einfache Migration:
In diesem Beispiel durchlaufen wir den Konstruktionsprozess UserPreferences und seine Einstellung sortOrder zu dem, was zuvor in der entsprechenden gespeichert wurde SharedPreferences Schlüssel-Wert-Paar oder einfach auf NONE gesetzt.
produceMigrations wird dafür sorgen migrate() wurde gestartet vor einem möglichen Zugriff auf Daten im Datenspeicher. Das bedeutet Ihre Migration ihm muss es gelungen sein bevor der DataStore weitere Werte aussendet und bevor er mit neuen Datenänderungen beginnt. Sobald Sie erfolgreich migriert haben, können Sie die Verwendung sicher einstellen SharedPreferenceswie Schlüssel nur einmal migriert und dann ENTFERNT von SharedPreferences.
Der produceMigrations akzeptiert die Liste DataMigration. Wir werden in späteren Episoden sehen, wie wir dies für andere Arten von Datenmigrationen verwenden können. Wenn Sie nicht migrieren müssen, können Sie dies ignorieren, da es eine gibt Ursprünglich listOf() bereitgestellt schon.
Einer der Hauptvorteile von DataStore gegenüber SharedPreferences ist seine ein geordneter Mechanismus zum Erfassen und Behandeln von Ausnahmen. Während SharedPreferences wirft Parsing-Fehler als Laufzeitausnahmen aus und lässt Raum für unerwartete, nicht abgefangene Abstürze, DataStore wirft aus IOException wenn beim Lesen/Schreiben von Daten ein Fehler auftritt.
Wir können dies sicher lösen, indem wir verwenden catch() Flow- und Broadcast-Betreiber getDefaultInstance():
Oder mit dem einfachen try-catch Blockschreiben:
Wenn eine andere Art von Ausnahme ausgelöst wird, sollten Sie sie besser erneut auslösen.
Wir deckten ab Protokollpufferich Das Proto von DataStore Implementierung – wann und wie man damit Daten liest und schreibt, wie man mit Fehlern umgeht und wie man sie überwindet SharedPreferences. Im nächsten und letzten Beitrag gehen wir noch einen Schritt weiter und sehen, wie sich der DataStore in Ihren einfügt Anwendungsarchitektur, wie man es mit Hilt injiziert und natürlich, wie man es testet. Seh dich später!
Wir werden uns diesen Beitrag ansehen DataStore-Einstellungeneiner von zwei Datenspeicher Implementierung. Wir werden weitermachen, wie erstellen, Daten lesen und schreiben und Ausnahmen behandelnund all das sollte Ihnen hoffentlich genügend Informationen liefern, um zu entscheiden, ob dies die richtige Wahl für Ihre Anwendung ist.
Einstellungen DataStore-Verwendungen Schlüssel/Wert-Paare um kleinere Datensätze zu speichern, ohne zuerst das Schema zu definieren. Dies könnte Sie daran erinnern SharedPreferences, aber nur in der Art und Weise, wie es Ihre Datenmodelle strukturiert. Es gibt ein verschiedene Vorteile bringt der DataStore durch seine SharedPreferences Vorgänger. Melden Sie sich schnell bei uns zurück vorherigen Postund schauen Sie sich den detaillierten Vergleich an, den wir dort gemacht haben. Wir werden uns das Folgende ansehen Preferences DataStore wie nur Preferenceswenn nicht anders angegeben.
Für eine kurze Zusammenfassung:
Bietet ein vollständig asynchrone API zum Herunterladen und Speichern von Daten mit der Kraft von Kotlin Korutina
Es bietet keine gebrauchsfertige synchrone Unterstützung – vermeidet direkt jegliche Arbeit, die den UI-Thread blockiert
Es stützt sich auf den internen Fehlersignalisierungsmechanismus von Flow, der Ihnen dies ermöglicht Ausnahmen sicher erfassen und verarbeiten beim Lesen oder Schreiben von Daten
Verarbeitet Transaktionsdatenaktualisierungen in einer Atomares Lesen-Modifizieren-Schreiben Arbeit, Bereitstellung stark SÄURE Garantien
Erlaubt einfache und schnelle Datenmigration
Wollen schnell migrieren von SharedPreferences mit minimale Änderungen und Sie fühlen sich ohne volle Sicherheit sicher genug? Wählen Einstellungen über Proto
Lassen Sie uns nun in etwas Code eintauchen und lernen, wie Einstellungen implementiert werden sollten.
Diese Beispielanwendung zeigt eine Liste von Aufgaben an, und der Benutzer kann sie nach ihrem abgeschlossenen Status filtern oder nach Priorität und Frist sortieren. Wir möchten ihre Auswahl speichern boolean für abgeschlossene Aufgaben ia Aufzählung sortieren im Datenspeicher.
Beginnen wir mit dem Hinzufügen der erforderlichen Abhängigkeiten:
💡 Ein kurzer Tipp: Wenn Sie Ihre Konstruktion minimieren möchten, fügen Sie Ihrer eigenen eine zusätzliche Regel hinzu proguard-rules.pro Datei, um zu verhindern, dass Ihre Felder gelöscht werden:
Sie interagieren mit den im DataStore gespeicherten Daten über eine Instanz DataStore<Preferences>. DataStore ist eine Schnittstelle, die den Zugriff auf dauerhafte Informationen gewährt. Einstellungen ist eine abstrakte Klasse ähnlich einer generischen Karte, die insbesondere in der Implementierung des Preferences DataStore verwendet wird, um Schlüssel-Wert-Paare Ihrer Daten zu verfolgen. Wir werden darüber sprechen MutablePreferences Unterklasse, wenn wir über das Schreiben von Daten sprechen.
Es wird empfohlen, zum Erstellen dieser Instanz einen Delegaten zu verwenden preferencesDataStore und Pass erforderlich name Streit. Dieser Delegierte ist a Kotlin-Eigenschaftserweiterung dessen Empfängertyp eine Instanz sein muss Contextanschließend für den Bau benötigt File Objekt, in dem DataStore Daten speichert:
Sie sollten nicht mehr als eine DataStore-Instanz für eine bestimmte Datei erstellen, weil es die gesamte Funktionalität des DataStore ruinieren kann. Daher können Sie ein Delegate-Konstrukt einmal auf der obersten Ebene Ihrer Kotlin-Datei hinzufügen und es in der gesamten Anwendung verwenden, um es als zu übergeben Einzelling. Wie das mit einer Suchtspritze geht, sehen wir uns in späteren Beiträgen an.
Schlüssel definieren
DataStore bietet eine schnelle Möglichkeit, Schlüssel für verschiedene Datentypen zu erstellen, z booleanPreferencesKey, intPreferencesKey und vieles mehr – Sie müssen nur bestehen Schlüsselname als Wert. Obwohl dies einige Einschränkungen für Datentypen mit sich bringt, sollten Sie dies im Hinterkopf behalten bietet keine endgültige Typsicherheit. Indem wir den bevorzugten Schlüssel eines bestimmten Typs bestimmen, hoffen wir das Beste und verlassen uns auf unsere Annahmen der Wert eines bestimmten Typs würde zurückgegeben. Wenn Sie der Meinung sind, dass Ihr Code so strukturiert ist, dass er sicher zu handhaben ist, können Sie gerne mit den Einstellungen fortfahren. Wenn nicht, erwägen Sie, den Bruder von Preferences zu verwenden, Proto-DataStorewie er prophezeit vollständige Sicherheit.
In unserer Anwendung UserPreferencesRepositoryWir geben alle Schlüssel an, die zur Strukturierung der Schlüssel/Wert-Paare unserer persistenten Daten erforderlich sind:
Zum Auslesen gespeicherter Daten, u UserPreferencesRepository wir belichten a Flow<Preferences> von dataStore.data. Dies ermöglicht ein effizientes Vorgehen der letzte erhaltene Zustand ich Sendungen bei jeder Änderung. Mithilfe von Kotlin-Datenklassen können wir alle Sendungen beobachten und den Datenspeicher transformieren Preferences unterliegen unseren UserPreferences Modell, nur verwenden Schlüssel/Wert-Paare wir sind interessiert an:
Flow wird immer entweder einen Wert ausgeben oder verwerfen Sie die Ausnahme beim Versuch, von der Festplatte zu lesen. Wir werden uns in späteren Abschnitten mit der Behandlung von Ausnahmen befassen. Der DataStore stellt außerdem sicher, dass die Arbeit immer erledigt wird Dispatchers.IO Ihr UI-Thread wird also nicht blockiert.
🚨 Erstellen Sie keine Cache-Repositories um den aktuellen Stand Ihrer Präferenzdaten abzubilden. Damit erlischt die DataStore-Garantie für Datenkonsistenz. Wenn Sie eine Aufnahme Ihrer Daten ohne ein Abonnement für weitere Flow-Shows benötigen, verwenden Sie sie stattdessen dataStore.data.first():
Wir werden die Aussetzung verwenden, um Daten zu schreiben DataStore<Preferences>.edit(transform: suspend (MutablePreferences) -> Unit) Funktion. Lassen Sie es uns aufschlüsseln:
DataStore<Preferences> Schnittstelle – wir verwenden derzeit den Datenspeicher als Beton Preferences Implementierung
transform: suspend (MutablePreferences) -> Unit – ein Suspend-Block, der verwendet wird, um diese Änderungen auf unsere persistenten Daten anzuwenden
MutablePreferences – variable Unterklasse Preferencesähnlich MutableMapwodurch wir Änderungen an unseren Schlüssel/Wert-Paaren vornehmen können
Als Beispiel werden wir unsere ändern SHOW_COMPLETED Flagge:
Die Bearbeitung von Daten erfolgt transaktional in einem Atomare Read-Modify-Write-Operation. Das bedeutet, dass es eine bestimmte Abfolge von Datenverarbeitungsvorgängen garantiert, während derer Daten für andere Threads gesperrt sind Konsistenz ich verhindert Rennbedingungen. Nur nach transform ich edit Corutins erfolgreich abgeschlossen, Daten werden dauerhaft auf der Festplatte gespeichert und datastore.data Der Fluss wird die Aktualisierung widerspiegeln.
🚨 Beachten Sie, dass dies die einzige Möglichkeit ist, den Status des DataStore zu ändern. Wartung u MutablePreferences Referenz und manuelle Mutation danach transform vervollständigt ändert die permanenten Daten nicht im DataStore, also sollten Sie nicht versuchen, es zu ändern MutablePreferences außen transform Block.
Wenn der Schreibvorgang aus irgendeinem Grund fehlschlägt, wird die Transaktion beendet und eine Ausnahme ausgelöst.
Wenn Sie es zuvor verwendet haben SharedPreferences in Ihrer Bewerbung und möchten Ihre Daten sicher an Preferences übertragen, können Sie verwenden SharedPreferencesMigration. Dazu braucht es Kontext, SharedPreferences den Namen und den optionalen Schlüsselsatz, den Sie migrieren möchten (oder lassen Sie es einfach so Ursprünglich MIGRATE_ALL_KEYS Wert).
Ansehen SharedPreferencesMigration Implementierung sehen Sie a getMigrationFunction() die dafür verantwortlich ist, alle erforderlichen, gespeicherten Schlüssel/Wert-Paare abzurufen und sie zu den Einstellungen hinzuzufügen gleichen Tasten. Bestehen SharedPreferencesMigration über dem produceMigrations ParameterpreferencesDataStore delegieren an einfach zu migrieren:
produceMigrations wird dafür sorgen getMigrationFunction() wurde gestartet vor einem möglichen Zugriff auf Daten im Datenspeicher. Das bedeutet Ihre Migration ihm muss es gelungen sein bevor der DataStore weitere Werte aussendet und bevor er mit neuen Datenänderungen beginnt. Sobald Sie erfolgreich migriert haben, können Sie die Verwendung sicher einstellen SharedPreferenceswie Schlüssel nur einmal migriert und dann ENTFERNT von SharedPreferences.
Der produceMigrations akzeptiert die Liste DataMigration. Wir werden in späteren Episoden sehen, wie wir dies für andere Arten von Datenmigrationen verwenden können. Wenn Sie nicht migrieren müssen, können Sie dies ignorieren, da es eine gibt Ursprünglich listOf() bereitgestellt schon.
Einer der Hauptvorteile von DataStore gegenüber SharedPreferences ist seine ein geordneter Mechanismus zum Erfassen und Behandeln von Ausnahmen. Während SharedPreferences wirft Parsing-Fehler als Laufzeitausnahmen aus und lässt Raum für unerwartete, nicht abgefangene Abstürze, DataStore wirft aus IOException wenn beim Lesen/Schreiben von Daten ein Fehler auftritt.
Wir können dies sicher lösen, indem wir verwenden catch() Flow-Operator kurz davor map() und Rundfunk emptyPreferences():
Oder mit dem einfachen try-catch Blockschreiben:
Wenn eine andere Art von Ausnahme ausgelöst wird, sollten Sie sie besser erneut auslösen.
Wir deckten ab DataStore-Einstellungen Implementierung – wann und wie man damit Daten liest und schreibt, wie man mit Fehlern umgeht und wie man sie überwindet SharedPreferences. Im nächsten Beitrag werden wir die gleichen Themen mit behandeln Proto-DataStore Umsetzung, also bleiben.
Willkommen bei Now in Android, Ihrem ständigen Leitfaden für Neues und Wichtiges in der Welt der Android-Entwicklung. Es ist lange her seit unserem letzten echten Update; Unser letzter Blog konzentrierte sich auf einige wichtige Momente im Jahr 2021, daher könnte diese Ausgabe besser „Kürzlich in Android“ betitelt werden.
Derselbe Inhalt wie in diesem Beitrag, aber mit weniger Details und unendlich mehr Geschichten.
Wir haben die erste Ausgabe gemacht Jetpack-Blick verfügbar, ein neuer Rahmen, der das Erstellen von App-Widgets für den Startbildschirm und andere Oberflächen schneller und einfacher machen soll. Glance bietet ähnliche moderne, deklarative Kotlin-APIs, die Sie gewohnt sind Jetpack komponieren, was Ihnen hilft, schöne App-Widgets mit viel weniger Code zu erstellen. Glance bietet einen grundlegenden Satz proprietärer Composables, die dabei helfen, „visuelle“ Erfahrungen zu erstellen – beginnend heute mit Anwendungs-Widget-Komponenten, aber mit mehr. Mithilfe der Jetpack Compose-Laufzeit übersetzt Glance diese Composables in RemoteViews, die im App-Widget angezeigt werden können.
Wir fingen an Jetpack Watch Face-Bibliothek von Grund auf in Kotlin geschrieben, einschließlich aller Funktionalitäten aus der Wearable Support Library zusammen mit vielen neuen Features wie:
Gesichtsformung der Uhr, die sowohl auf der Uhr als auch auf dem Telefon hält (ohne dass eine eigene Datenbank oder eine begleitende Anwendung erforderlich ist).
Unterstützung für ein WYSIWYG UI zum Konfigurieren des Zifferblatts auf dem Telefon.
Kleinere, separate Bibliotheken (die nur das enthalten, was Sie benötigen).
Akkuverbesserungen durch die Förderung guter Akkunutzungsmuster außerhalb der Box, z. B. automatische Reduzierung der interaktiven Bildrate, wenn der Akku fast leer ist.
Neue Snapshots-APIs, damit Benutzer Übersichten über Änderungen an ihrer Uhr in Echtzeit sowohl auf der Uhr als auch auf dem Telefon sehen können.
Wenn Sie immer noch die Wearable Support Library verwenden, empfehlen wir Ihnen dringend, zu den neuen Jetpack-Bibliotheken zu wechseln, um die Vorteile der neuen APIs und bevorstehenden Funktionen und Fehlerbehebungen zu nutzen.
Wir begannen eine ein aktualisierter Leitfaden zur Anwendungsarchitektur die Best Practices enthält. Da Android-Apps immer größer werden, ist es wichtig, Code mit einer integrierten Architektur zu entwerfen, die die Skalierung der App ermöglicht, die Qualität und Robustheit verbessert und das Testen erleichtert. Der Leitfaden enthält Seiten für Benutzeroberfläche, Domainich Daten Ebenen, einschließlich eines tiefen Eintauchens in komplexere Themen, wie z. B. den Umgang mit UI-Ereignissen. Wir haben auch eine Lernweg um dich da durch zu bringen.
Das haben wir angekündigt Anwendungen öffnen für Google Play Games auf dem PC als Beta in Korea, Taiwan und Hongkong, sodass Beta-Benutzer den Google Play Games-Katalog auf ihrem PC über eine von Google erstellte eigenständige App spielen können. Der Entwicklerseite hat ein Formular, um Interesse zu bekunden, zusammen mit Informationen zur Erstellung Ihres Android-Spiels auf dem PC. Enthält viele der gleichen Updates, die Sie zur Optimierung Ihres Spiels für Chrome OS-Geräte durchführen, z. B. Unterstützung für Maus- und Tastatursteuerung.
MAD-Fähigkeiten entwickelt sich ständig weiter, mit technischen Inhalten zur modernen Entwicklung von Android.
Erste, Murat behandelte ausführlicher die Konstruktion benutzerdefinierter Plugins, einschließlich der Artifact-API zusätzlich zu der zuvor behandelten Variant-API. Es demonstriert die Konstruktion eines Add-Ons, das den im Anwendungsmanifest angegebenen Versionscode automatisch mit der Git-Version aktualisiert. Mit der Veröffentlichung von AGP 7.0 können Sie diese APIs verwenden, um Eingaben zu steuern, um mittlere und letzte Artefakte zu erstellen, zu lesen, zu ändern oder sogar zu ersetzen.
Nächste, Alex SaveauBetreuer von Gradle Play Publisher und Version Orchestrator, bietet eine Anleitung zur Bearbeitung Ihrer Android-Build-Artefakte mit AGP und Gradle API.
Simona gestartet MAD-Fähigkeiten: DataStore. DataStore ist eine nicht blockierende oder Thread-sichere Bibliothek in Android Jetpack, die eine sichere und konsistente Möglichkeit zum Speichern kleiner Datenmengen wie Einstellungen oder Anwendungsstatus bietet und SharedPreferences ersetzt. Stellt eine Implementierung bereit, die typisierte Objekte speichert, die von Protokollpuffern unterstützt werden (Proto DataStore), und eine Implementierung, die Schlüssel/Wert-Paare speichert (Preferences DataStore).
Aber warte! Als ob das nicht genug wäre, gibt es noch mehr VERRÜCKTE Inhalte!
Sie können alle Hinweise zum AndroidX-Release sehen Hier.
Alexschrieb über die letzten Updates für Jetnews was sein Verhalten auf großen und kleinen Mobilgeräten verbessert. Es beschreibt unseren Design- und Entwicklungsprozess, damit Sie unsere Philosophie und die zugehörigen Implementierungsschritte kennenlernen können, um eine Anwendung zu erstellen, die für alle Jetpack Compose-Bildschirme optimiert ist, einschließlich der Planung einer Liste / eines Details.
Paulschrieb über Drag & Drop und wie man Android Jetpack macht DragAndDrop-Alpha-Bibliothek erleichtert die Handhabung von in Ihre Anwendung eingefügten Daten.
Der Reihe Barrierefreiheit Es geht weiter und weiter, beginnend mit einer Episode über die richtige Implementierung von UI-Elementen, die nach einer bestimmten Zeit verschwinden.
Wir behandeln auch wie Scanner für Barrierefreiheit kann Ihnen dabei helfen, Ihre App für alle Benutzer zu verbessern, indem Verbesserungen der Barrierefreiheit vorgeschlagen werden.
Mayuri abgedeckte Best Practices für Siehe Nächste API auf Android TV und Google TV, wodurch die Interaktion mit Ihrer App gesteigert wird, indem Ihre Inhalte in der Warteschlange „Als Nächstes ansehen“ angezeigt werden.
Es gab drei Episoden Android-Entwickler hinter den Kulissen seit dem letzten Now in Android veröffentlicht. Überprüfen Sie sie unter dem folgenden Link oder in Ihrem bevorzugten Podcast-Client:
Datenspeicher ist eine Jetpack-Datenspeicherbibliothek, die eine sichere und konsistente Möglichkeit bietet, kleine Datenmengen wie Einstellungen oder Anwendungsstatus zu speichern. Es basiert auf Kotlin Korutine und Flow die eine asynchrone Datenspeicherung ermöglichen. Es zielt darauf ab, zu ersetzen SharedPreferences, weil es sicher ist und nicht blockiert. Es bietet zwei verschiedene Implementierungen: Proto-DataStoredas typisierte Objekte speichert (unterstützt von Protokollpuffer) ich DataStore-Einstellungen, die Schlüssel/Wert-Paare speichert. Machen wir weiter, wenn wir es einfach benutzen DataStoregilt dies für beide Implementierungen, sofern nicht anders angegeben.
Wir werden uns diesen Blogbeitrag genauer ansehen Datenspeicher – wie es funktioniert, welche Implementierungen es bietet und ihre individuellen Anwendungsfälle. Wir werden uns auch ansehen, welche Vorteile und Verbesserungen es bringt SharedPreferences und warum sich der DataStore dadurch lohnt.
Sie haben es wahrscheinlich benutzt SharedPreferences in Ihren Anwendungen. Es ist auch wahrscheinlich, dass Sie Probleme mit hatten SharedPreferences welche sind schwer zu reproduzieren – Erkennen ungewöhnlicher Abstürze in Ihren Analysen aufgrund nicht erfasster Ausnahmen, UI-Blockierung oder beim Tätigen von Anrufen oder inkonsistenten, persistenten Daten in Ihrer Anwendung. Datenspeicher wurde entwickelt, um all diese Probleme zu lösen.
Schauen wir uns einen direkten Vergleich zwischen an SharedPreferences und Datenspeicher:
Vergleich von DataStore-Implementierungen mit SharedPreferences
Asynchrone API
Bei den meisten Speicher-APIs müssen Sie häufig benachrichtigt werden asynchron wenn die Daten geändert werden. SharedPreferences bietet an manche Async-Unterstützung, aber nur um Updates zu geänderten Werten per zu erhalten OnSharedPreferenceChangeListener. Dieser Rückruf wird jedoch weiterhin aufgerufen Haupt-Bedroung. Ebenso können Sie es verwenden, wenn Sie Ihre Dateispeicherarbeit in den Hintergrund stellen möchten SharedPreferencesapply()aber denken Sie daran, dass es sein wird UI-Thread blockieren er fsync(), was möglicherweise Ruck und ANRs verursacht. Dies kann jedes Mal passieren, wenn der Dienst gestartet oder beendet wird oder wenn eine Aktivität angehalten oder beendet wird. Im Vergleich dazu bietet der DataStore a vollständig asynchrone API um Daten herunterzuladen und zu speichern, indem Sie die Leistung von Kotlin und Flow nutzen und das Risiko einer Blockierung Ihrer UI-Threads verringern. Für diejenigen, die mit Kotlin Flows nicht vertraut sind, es ist nur ein Wertstrom, der asynchron berechnet werden kann.
Synchronbetrieb
SharedPreferences Die API unterstützt den synchronen Box-Betrieb. Es ist jedoch synchron commit() Um persistente Daten zu ändern, mag es sicher erscheinen, UI-Threads aufzurufen, aber es funktioniert tatsächlich schwieriger I / O-Operationen. Dies ist ein riskantes Szenario, das zu ANRs und UIs führen kann und dies auch oft tut. Um dies zu verhindern, muss DataStore bietet keine gebrauchsfertige synchrone Unterstützung. DataStore speichert die Einstellungen in einer Datei und führt alle Datenoperationen im Hintergrund durch Dispatchers.IO, Sofern nicht anders angegeben, bleibt Ihr UI-Thread entsperrt.
Es ist jedoch möglich, DataStore und synchronen Betrieb mit ein wenig Hilfe des Corutin-Builders zu kombinieren, wie wir später sehen werden.
Fehlerbehandlung
SharedPreferences kann Analysefehler als Laufzeitausnahmen ausgeben, wodurch Ihre Anwendung anfällig für Abstürze wird. Zum Beispiel die ClassCastException ist eine häufige Ausnahme, die von der API ausgelöst wird, wenn falscher Datentyp Wird benötigt. DataStore bietet einen Weg jede Ausnahme abfangen Sie kommen beim Lesen oder Schreiben von Daten und verlassen sich auf den Fehlersignalisierungsmechanismus von Flow.
Sicherheitsstufe
Die Verwendung von Key/Value Map-Paaren zum Speichern und Abrufen von Daten bietet keine Typsicherheit. Mit Proto DataStore können Sie jedoch das Schema für Ihr Datenmodell vordefinieren und den zusätzlichen Vorteil nutzen vollständige Sicherheit.
Datenkonsistenz
SharedPreferences‘Das Fehlen von Atomaritätsgarantien bedeutet, dass Sie nicht darauf vertrauen können, dass Änderungen in Ihren Daten immer und überall widergespiegelt werden. Dies kann gefährlich sein, zumal der ganze Sinn dieser API dauerhafte Datenspeicherung. Zum Vergleich DataStore vollständig transaktionale API bietet stark SÄURE Garantien, da die Daten in aktualisiert werden Atomares Lesen-Modifizieren-Schreiben Betrieb. Es bietet auch “nach dem Schreiben lesen„Konsistenz, die die Tatsache widerspiegelt, dass sich alle abgeschlossenen Aktualisierungen in den gelesenen Werten widerspiegeln.
Migrationsunterstützung
SharedPreferences Es gibt keinen integrierten Migrationsmechanismus – es liegt an Ihnen, ein mühsames, fehleranfälliges Mapping von Ihrem alten Warehouse auf das neue durchzuführen und dann aufzuräumen. All dies erhöht die Chancen Laufzeitausnahmen, da Sie leicht auf Probleme mit der Nichtübereinstimmung von Datentypen stoßen könnten. Der DataStore bietet jedoch einen Weg einfache Datenmigration darin, zusammen mit der geplanten Umsetzung für SharedPreferences-on-DataStore-Migration.
Jetzt haben wir gesehen, welche Vorteile der DataStore bietet SharedPreferenceslassen Sie uns darüber sprechen, wie Sie zwischen den beiden Implementierungen wählen können – Einstellungen und Proto DataStore.
EinstellungenDatenspeicher liest und schreibt datenbasiert Schlüssel/Wert-Paare, ohne vorherige Definition der Regelung. Auch wenn das vielleicht ähnlich klingt SharedPreferences, denken Sie an alle oben genannten Verbesserungen, die der DataStore mit sich bringt. Lassen Sie sich nicht von ihrem Teilen täuschen.”Einstellungen„Bei der Benennung – sie haben nichts gemeinsam und kommen von zwei völlig getrennten APIs.
ProtoDatenspeicher Geschäfte getippte Objektemit Unterstützung Protocol Buffers, bietet Typsicherheit und eliminiert die Notwendigkeit von Schlüsseln. Protobuffs sind schneller, kleiner, einfacher und weniger mehrdeutig als XML und andere ähnliche Datenformate. Wenn Sie sie noch nie benutzt haben, haben Sie keine Angst! Dies ist sehr einfach zu lernen. Obwohl der Proto DataStore erfordert, dass Sie einen neuen Serialisierungsmechanismus erlernen, sind wir von seinen Vorteilen besonders überzeugt Typ Sicherheites ist es wert.
Vergleich von DataStore-Implementierungen
Bei der Wahl zwischen den beiden müssen Sie Folgendes berücksichtigen:
Wenn Sie mit arbeiten Schlüssel/Wert-Paare zum Lesen und Schreiben von Daten, die Sie möchten schnell migrieren von SharedPreferences mit minimalen Änderungen, während Sie immer noch die Vorteile von DataStore-Verbesserungen nutzen und sich ohne Typsicherheitsprüfungen sicher genug fühlen, können Sie mit gehen DataStore-Einstellungen
Wenn Sie Protokollpuffer für den zusätzlichen Vorteil einer verbesserten Lesbarkeit lernen möchten, wenn Ihre Daten Arbeit erfordern komplexere Klassenwie Aufzählungen oder Listen, und die Sie haben möchten vollständige Sicherheit unterstützen, während Sie dies tun, können Sie versuchen Proto-DataStore
Du darfst fragen –“Nun, warum nicht einfach nutzen Zimmer um meine Daten zu speichern?“. Und das ist eine berechtigte Frage! Mal sehen, wo Room in all das hineinpasst.
Wenn Sie mit arbeiten müssen komplexe Datensätze größer als ein paar 10 KB ist, ist es sehr wahrscheinlich, dass Sie es brauchen werden Teilaktualisierungen oder Referenzintegrität zwischen verschiedenen Datentabellen. In diesem Fall sollte der Einsatz erwogen werden Zimmer.
Wenn Sie jedoch mit arbeiten kleiner und einfacherDatensätzewie z. B. Anwendungseinstellungen oder Status, und daher keine Teilaktualisierungen oder Referenzintegrität erfordern, sollten Sie auswählen Datenspeicher.
So wählen Sie zwischen DataStore und Room
Wir sind näher ins Detail gegangen Datenspeicher – wie es funktioniert, welche Änderungen und Verbesserungen es bringt und wie man sich zwischen den beiden Implementierungen entscheidet. Wir werden in den nächsten beiden Blogbeiträgen weiter darauf eingehen Proto und Preferences DataStore – wie man Daten erstellt, liest und schreibt, alle Fehler behandelt und wie man sie überwindet SharedPreferences. Bleiben Sie dran!
Willkommen bei Now in Android, Ihrem ständigen Leitfaden für Neues und Wichtiges in der Welt der Android-Entwicklung. Wenn das Jahr 2021 näher rückt, lassen Sie uns über einige der großartigen Dinge nachdenken, die wir dieses Jahr für Android getan haben.
Android 12L befindet sich ebenfalls in der Beta-Phase, wodurch Android 12 auf großen Bildschirmen noch besser wird. Enthält Tools für intuitiveres Multitasking, Kompatibilitätsverbesserungen und mehr! Probieren Sie es noch heute aus.
Einheitsabdeckungen 3 Navigation wo Sie lernen, durch verschiedene Bildschirme innerhalb Ihrer App zu navigieren, sie einzugeben und zurückzukehren.
Einheitsabdeckungen 4 Internetverbindung. Sie schreiben asynchronen Code, lernen HTTP und REST kennen, um Daten aus dem Internet abzurufen, und verwenden die Coil-Bibliothek, um Bilder in Ihrer Anwendung anzuzeigen.
Einheit 5 umfasst Datenkonsistenz Hier erfahren Sie, wie Sie Daten auf dem Gerät speichern, was Teil der Gewährleistung einer reibungslosen und konsistenten Benutzererfahrung ist, auch bei Netzwerkausfällen.
Einheitsabdeckungen 6 Arbeitsmanager wo Sie die Android Jetpack WorkManager-API verwenden, um Hintergrundarbeiten zu planen, die auch dann weiter funktionieren, wenn die App geschlossen oder das Gerät neu gestartet wird.
Wir hatten ein fantastisches Jahr für MAD Skills und veröffentlichten mehrere Serien von Videos und Blogs, die viele wichtige Themen abdecken:
Kotlin und Jetpack – Erlernen Sie die Grundlagen von Jetpack KTX-Bibliotheken, wie Sie Rückrufe mit Rollen und Flow vereinfachen und wie Sie Room / WorkManager-APIs verwenden und testen.
Bewegungslayout – Erfahren Sie, wie Sie MotionLayout und sein Designtool verwenden, um reichhaltige, animierte Erlebnisse zu erstellen.
Arbeitsmanager – Erfahren Sie, wie Sie kritische Hintergrundarbeiten mit WorkManager planen: von der grundlegenden Verwendung über Threads bis hin zu benutzerdefinierten Konfigurationen und mehr.
Navigation – Lernen Sie die Grundlagen der Navigationskomponente, spezifische Funktionen von Tools und APIs zum Erstellen von und Navigieren zu Zielen.
Leistung – Erfahren Sie mehr über die Verwendung von System-Tracking und Sampling-Profiling zum Debuggen von Anwendungsleistungsfehlern.
Griff – Erfahren Sie, wie Sie Hilt hinzufügen und verwenden, um Ihrer Android-App Sucht hinzuzufügen, Best Practices zum Testen mit Hilt und erweiterte Inhalte.
Paging – Erlernen Sie die Grundlagen von Seiten, von grundlegenden Typen bis hin zur Verknüpfung mit Ihren UI-Elementen.
Gradl – Erfahren Sie, wie Sie Ihre Version konfigurieren, den Build-Prozess an Ihre Bedürfnisse anpassen und wie Sie Ihre eigenen Add-Ons schreiben, um Ihre Version weiter zu erweitern.
Vielen Dank, dass Sie sich engagieren, großartige Apps erstellen, Feedback geben und Teil unserer weltweiten Entwickler-Community sind. Wir werden 2022 mit weiteren Android-Updates zurück sein! 😍😍😍