Search for:

Jetzt in Android #55. Android Studio, DataStore, Glance… | lähde: Manuel Vivo | Android-Entwickler Februar 2022

Er macht Illustrationen Virginia Poltrack

DataStore und synchroner Betrieb. In den folgenden Beiträgen unseres Jetpacks… | von Simona Stojanovic Android-Entwickler Februar 2022

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.

End-to-End-Test-Push-Nachrichten mit Firebase Cloud Messaging | von Josef Raska Februar 2022

Eine der Herausforderungen der mobilen Entwicklung ist der Umgang mit Integrationen von Drittanbietern und insbesondere das automatische Testen solcher Integrationen. Push-Messaging mit FCM ist ein solcher Fall, in dem die Auswirkungen von Integrationsstörungen hoch sein können, insbesondere während einer Kampagne oder der Ausstellung einer Notfallkorrektur. Sehen wir uns an, wie wir Tests vollständig automatisieren können, um sicherzustellen, dass unsere FCM-Integrationen nie wieder fehlschlagen.

Instrumenteller Android-Test, der den Push-Flow bestätigt

Firebase Cloud Messaging ist zum De-facto-Standard für Push-Messaging für Android-Anwendungen geworden. Es ist eine plattformübergreifende Messaging-Lösung, mit der Sie Nachrichten zuverlässig und kostenlos versenden können.

FCM-Architektur – Quelle

Der gesamte Ablauf von Push-Benachrichtigungen wird erklärt Hier.

  1. Die Anwendung erhält über das Firebase SDK ein Push-Token vom FCM-Back-End.
  2. Die Anwendung überträgt dieses Token an den Anwendungsserver.
  3. Die Serveranwendung löst eine Push-Nachricht mit dem geladenen Token und der HTTP-Anforderung an das FCM-Backend aus.
  4. Eine Push-Nachricht erreicht die Anwendung und löst die gewünschte Aktion aus.
Testen des Push-Nachrichtenflusses

Der Durchfluss umfasst mehrere bewegliche Teile, und das Testen kann schwierig und zeitaufwändig sein. Noch wichtiger ist, dass es lange dauern kann, bis eine der Integrationen fehlschlägt, bis dies erkannt wird, und es kann im ungünstigsten Moment passieren, wenn Sie Ihren Benutzern tatsächlich Push-Nachrichten senden möchten.

Wenn wir den Nachrichtenfluss von Ende zu Ende zuverlässig testen wollen, müssen wir dafür mehrere Probleme lösen.

  1. Synchronisieren Sie das Senden und Empfangen von Push-Nachrichten.
  2. Haben Sie ein Gerät, das ein FCM-Token empfängt.
  3. Verwenden Sie einen Token mit FCM-Hintergrund, um eine Push-Nachricht auszulösen.
  4. Lassen Sie den Test auf die Push-Nachricht warten.
  5. Stellen Sie sicher, dass die Anwendung die richtige Push-Nachricht erhalten hat.

Problem 1 kann gelöst werden, indem der instrumentelle Test der Anwendung in den Hintergrund der Anwendung gestellt wird und mit dem FCM-Hintergrund kommuniziert wird. Auf diese Weise vermeiden wir den zusätzlichen beweglichen Teil des Anwendungshintergrunds und integrieren die vollständige Flusskontrolle in unseren Test.

Instrumenteller Android-Test, der den Push-Flow bestätigt

Problem 2 – die Notwendigkeit eines echten Geräte-Tokens kann durch die Verwendung von gelöst werden Firebase-Testlabor physische Geräte über Gcloud-CLI ich Gradle-Widget Tests durchzuführen. Ein instrumentiertes Testpaket, das auf einem tatsächlichen Gerät ausgeführt wird, verfügt unmittelbar nach dem Start der App über ein Push-Token, und wir können das Token direkt in unserem Testcode verwenden.

Darauf folgt Fehlerbehebung 3 – Ausführen eines Push durch das FCM-Backend. Alles, was wir dafür brauchen, ist ein Push-Token und eine einfache Nachrüstung PushServerClientwas umsetzen wird FCM-HTTP-Protokoll. Dann müssen wir den FCM-Autorisierungsschlüssel in unserem Gerätetest bestehen, was durch Weiterleitung von a erfolgen kann Instrumentelles Testargument auf das Gerät über gcloud Parameter von Umgebungsvariablen er fügte hinzu Widget Gradle.

Es kann einige Zeit dauern, bis das FCM-Backend eine Push-Nachricht sendet und die Anwendung sie im Testlabor empfängt. Wir müssen sicherstellen, dass der Test nicht weiter behauptet, bevor die Nachricht eintrifft, um sicherzustellen, dass der Test zuverlässig ist.

Am Ende sieht der Test so aus:

Sie finden die Vollversion Hier.

Aus der abschließenden Behauptung können wir ersehen, dass der gesamte Kurs wie erwartet verlaufen ist. Dieser Test bestätigt, dass die Anwendung ausgeführt wird Einstellungsfenster bevor Sie zu navigieren über den Bildschirm nachdem eine Push-Nachricht mit dieser tiefen Verbindung eintrifft. (Video vom Test)

Wir haben jetzt einen vollautomatisierten Test, der den Ablauf des Empfangs von Push-Nachrichten aus dem FCM-Hintergrund durchläuft und überprüft, ob die Anwendung sie ordnungsgemäß verarbeitet.

Die durch eine Push-Nachricht ausgelöste Aktion hängt weitgehend von Ihrer Anwendung ab, sodass die Art und Weise, wie Sie überprüfen, ob sie korrekt behandelt werden, unterschiedlich sein wird. Hier ist entscheidend, dass die Push-Nachricht ankommt und die Anwendung entsprechend darauf reagiert.

Unzuverlässigkeit ist immer ein Problem, wenn es um Tests geht, die sich wie dieses in ein Live-Backend eines Drittanbieters integrieren lassen. Das Referenz-Repo wurde implementiert metrischer Testdie uns eine gute Antwort auf diese Frage geben kann.

Die Tests wurden zuverlässig einen Monat lang auf 2 verschiedenen Firebase Test Lab Geräten mit durchgeführt 260 erfolgreiche Läufe in Folge.

Daten zur Leistung von Push-Messaging-Tests 260 von 260 haben bestanden

Somit ist die Antwort klar – Ja, der Test ist zuverlässig und funktioniert derzeit gut mit dem P90 1,6 Sek und weniger als 0,6 s für die mittlere Zeit. Dies bedeutet, dass die Dauer mit anderen Espresso UI-Tests vergleichbar ist und sich gut in jedes Testpaket einfügen lässt.

Der P90-Push-Messaging-Test beträgt 1,627 Sekunden

Das Testen der Automatisierung Ihrer Push-Nachrichten-Szenarien kann Ihnen viele Risiken zu geringen Kosten ersparen und Ihre Push-Nachrichten-Integration zum Vergnügen für eine sichere Wiederholung machen. Ingenieure können sogar Tests verwenden, um neue Push-Szenarien zu testen und die TDD-Form ohne die mühsamen manuellen HTTP-Anforderungen des FCM-Backends zu erreichen.

Wie testen Sie Ihre Drittanbieter-Integrationen? Automatisieren Sie Tests? Lass es mich in den Kommentaren wissen.

Viel Glück beim Codieren!

DataStore- und Kotlin-Serialisierung von Simona Stojanovic Android-Entwickler Februar 2022

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 Serialisierung mehrere 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’s writeTo() 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’s writeTo() 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.

JankStats wird Alpha. Bibliothek für echte Mülljagd… | von Chet Haase | Android-Entwickler Februar 2022

Illustration von Virginia Poltrack

Eine Bibliothek, die Janko in der realen Welt verfolgt

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:

val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView,
newState: Int)
{
val metricsState = metricsStateHolder?.state ?: return
when (newState) {
RecyclerView.SCROLL_STATE_DRAGGING -> {
metricsState.addState("RecyclerView", "Dragging")
}
RecyclerView.SCROLL_STATE_SETTLING -> {
metricsState.addState("RecyclerView", "Settling")
}
else -> {
metricsState.removeState("RecyclerView")
}
}
}
}

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:

AndroidX-Projekt: JankStats ist dabei androidx.metrics-Bibliothek in AndroidX.

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.

So herunterladen das, damit spielen, und lassen Sie uns wissen, wenn Sie irgendwelche Probleme haben. Und am wichtigsten; Finden und beheben Sie diese Leistungsprobleme! Ihre Kunden warten auf Sie – lassen Sie sie nicht zu lange warten!

DataStore- und Injektionsabhängigkeit von Simona Stojanovic Android-Entwickler Februar 2022

Simona Stojanovic

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.

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

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

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 TaskActivity onCreatedenn seine Abhängigkeiten werden nun eingefügt:

Proto DataStore einfügen

Das ist es! Sie können die App jetzt ausführen und überprüfen, ob alle Abhängigkeiten jetzt korrekt eingefügt wurden.

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.

Einführung von Jetpack Compose in das bestehende Projekt von Ziv Kesten | Februar 2022

Erstellen Sie mit “Erinnern” eine erweiterbare Statusansicht.

Ziv Kastanie
Bild von Ziv Kesten

Betrachten wir zunächst einen Einzelfall des Objekts, das wir bauen.

  • Text, der den Untertitel des Artikels enthält.
  • Rechtspfeil-Symbol (das animiert wird, sich vertikal zu drehen, wenn wir ein Element erweitern).
@Composable
ExpandableListItem() {
Card(...) {
Row(...) {
TitleAndSubtitle(...)
Icon(...)
}
}
}

Card ein vom System geliefertes Verbundbauteil ist, kann dies einige Zeit in Anspruch nehmenelevation ich shape als Parameter, und wir können es mit a versorgenmodifier für alles andere, was wir brauchen.
Der Card ist ein Container für unser erweiterbares Listenelement, damit wir es versenden elevation und einigemodifiers :

  • padding() – Es gibt uns Platz von den Rändern.
  • clip(RoundedCornerShape(*.dp)) – wird die Karte der gelieferten beifügen RoundedCornerShape .
  • clickable() – ergibt ein Lambda, das wir später zur Abwechslung verwenden können Zustand zusammengesetzt
Card(
elevation = 4.dp,
modifier = Modifier
.fillMaxWidth()
.padding(start = 15.dp, top = 15.dp, end = 15.dp)
.clip(RoundedCornerShape(8.dp))
.clickable { // We will deal with the click event later }
)

Bei uns Card wir haben Row (Horizontales Äquivalent LineraLayout), die Titel und ein Symbol enthält.

Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {...}

U Row legen wir fest TitleAndSubtitle ich Icon die horizontal ausgerichtet werden.

Row(...) {
TitleAndSubtitle(
title = "Expandable item title",
subtitle = "There are more items below! 👇"
)
Icon(...)
}
@Composable
fun TitleAndSubtitle(
title: String,
subtitle: String
) {
Column(verticalArrangement = Arrangement.Center) {
Text(text = title)
Text(text = subtitle)
}
}

Der Icon ist ein zusammenbaubares System, wir geben es ihm imageVector die wir als Teil der kompositorischen Abhängigkeit erhalten, an align Modifikator und etwas Neues, das wir noch nicht gesehen haben … a graphicsLayer.

Icon(
imageVector = Icons.Default.ArrowDropDown,
modifier = Modifier
.align(CenterVertically)
.graphicsLayer(...)
)

Der graphicsLayer Modifikator

GraphicsLayer ist ein Modifikator, der zum Anwenden von Effekten auf Inhalte verwendet wird, z. B. Skalierung, Drehung, Deckkraft, Schatten und Beschneidung.
In unserem Fall möchten wir das Pfeilsymbol so drehen, dass sich der Pfeil nach oben dreht, wenn das Element erweitert wird.

Icon(
modifier = Modifier
.graphicsLayer(
rotationZ = animateFloatAsState(
if (expanded) 180f else 0f).value,
)
)

In Jetpack Compose zeigt das deklarative UI-Framework wieder nur Elemente, die ihre eigenen hatten Kondition geändert, wenn wir darüber sprechen Kondition Im Zusammenhang mit der Compose-Benutzeroberfläche beziehen wir uns normalerweise speziell auf einige Funktionsvariablen, die enthalten oder darstellen Kondition.

@Composable
ExpandableListItem() {
var expanded by remember { mutableStateOf(false) }
Card(modifier = Modifier.clickable { expanded = !expanded}) {
Row(...) {
TitleAndSubtitle(...)
Icon(...)
}
}
}

mutableStateOf

Wir nehmen die Initialen Kondition das Objekt, das ist falsch (extended = false) und als Standard übergeben mutableStateOf:

mutableStateOf ist eine reaktive Strömung, ähnlich LiveDate oder StateFlow und wird boolesche Werte ausgeben, wenn wir uns ändern erweitert Variable.

merken

Wir wickeln mutableStateOf tok ua remember blockieren, damit es bei allen Neuzusammenstellungen nicht vergessen wird, sonst wird das Kondition wird die Voreinstellung sein falsch jedes Mal ExpandableListItem namens.

Jetzt müssen wir am Ende unserer Komponente einen weiteren Abschnitt hinzufügen,

@Composable
ExpandableListItem() {
var expanded
Card(...) {
/// Wrap the row in a Column
Column {
Row(...) {
TitleAndSubtitle(...)
Icon(...)
}

// And add the extra items sections
Column {
ExtraItem(item = Item())
ExtraItem(item = Item())

}
}
}
}
data class Item (
val title: String,
val date: String
)
@Composable
fun ExtraItem(item: Item) {
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = item.title)
Text(text = item.date)
}
}
//// Extra items sections

Divider(modifier = Modifier.height(1.dp))
Column(modifier = Modifier.padding(...)) {

Spacer(modifier = Modifier.height(10.dp))
ExtraItem(item = Item())

Spacer(modifier = Modifier.height(10.dp))
Divider(modifier = Modifier.height(1.dp))
Spacer(modifier = Modifier.height(10.dp))

ExtraItem(item = Item())

Spacer(modifier = Modifier.height(10.dp))
Divider(modifier = Modifier.height(1.dp))
Spacer(modifier = Modifier.height(10.dp))

ExtraItem(item = Item())

}

Eine der wunderbarsten Komponenten, die die Abhängigkeit vom Kompilieren einer Benutzeroberfläche beinhaltet, ist AnimatedVisibility zusammensetzbar.

@Composable
fun ExpandableListItem() {
var expanded by remember { mutableStateOf(false) }
Card() {
Row() {
TitleAndSubtitle()
Icon()
}
AnimatedVisibility(visible = expanded) {
Column {
ExtraItem(item = Item())
ExtraItem(item = Item())
}
}
}
}

Der AnimationSpec speichert die Animationsspezifikation, wir können sie verwenden, um sie zu definieren Genuss, Dauer, Verzögerungen, und andere Spezifikationen im Zusammenhang mit der Anpassung von Animationen.
Wenn wir Animationen wie z erweitern ich reduzieren Animationen für unsere Benutzeroberfläche können wir als verwenden.

AnimatedVisibility(
visible = expanded,
enter = expandVertically(
animationSpec = tween(
durationMillis = 300, easing = FastOutLinearInEasing)
)
,
exit = shrinkVertically(
animationSpec = tween(
durationMillis = 300, easing = FastOutLinearInEasing)
)

)

Wir haben heute viel gelernt! Wir haben den Pfeil mit animiert graphicsLayer Modifikator, mit dem wir die Sichtbarkeit animiert haben AnimatedVisibilityund wir haben gelernt, wie man es benutzt Kondition in Jetpack Compose mit remember ich mutableStateOf.

Google Assistant Slices für Android – Teil 2 | Lähde: Cédric F | Februar 2022

Enge Integration der Android-Anwendung mit dem Assistenten

Cédric F

U Vorheriger Artikelhaben wir gesehen, wie Sie Ihrer App Google Assistant-Unterstützung hinzufügen. Jetzt ist es an der Zeit, einen Schritt weiter zu gehen und eine wunderbare Benutzererfahrung direkt in Google Assistant bereitzustellen, sodass der Benutzer die App nicht ausführen muss, um damit zu interagieren. Dies wird dank Slices erledigt.

Slices sind kleine Karten Benutzeroberfläche, das Google Assistant enthält, um eine umfassendere Benutzererfahrung zu bieten. Sie können aus der API extrahierte Informationen sowie Bilder und Aktionsschaltflächen enthalten.

Sie sind eine Möglichkeit, mit Ihrer App zu interagieren, ohne im Vollbildmodus ausgeführt zu werden. Die Benutzererfahrung ist für Google Assistant kontextbezogen und dialogorientiert.

Es werden Scheiben verwendet grundlegende UI-Blöcke wie Liste, Kopfzeile, Zeile, Bilder, Schaltflächen … Ein Programmierer kann eine Benutzeroberfläche auf deklarative Weise wie Jetpack Compose erstellen.

Slices bieten eine schnelle Möglichkeit, auf die Funktion einer App zuzugreifen, also halten Sie es einfach.

Beispiele für Scheiben

Ähnlich wie bei App Action müssen Slices in deklariert werden shortcuts.xml Google bietet eine große Menge vordefinierter Aktionen / Funktionen an, überprüfen Sie meine Vorheriger Artikel.

Sie können einen untergeordneten Knoten innerhalb der Optionen hinzufügen slice und bieten a url-template Diese Vorlage wird zum Ausführen von Slice verwendet.

Beachten Sie, dass empfohlen wird, “Inhalt” als Schema zu verwenden.

<capability android:name="actions.intent.OPEN_APP_FEATURE">
<slice>
<url-template
android:name="content://com.example.android.app.provider/slice{?feature}" />

</slice>
</capability>

Der Slice-Provider ist für die Erstellung eines Slice-Objekts mit einem URI (URL-Vorlage oben) zuständig.

Sie sollten fortfahren SliceProvider und implementieren Sie 2 Methoden:

  • onBindSlice () benötigt Uri, und was Sie tun müssen, ist, diesen Uri Ihrem Clip zuzuordnen und Slice wiederherzustellen
  • onCreateSliceProvider (), können Sie vorläufige Aufgaben erledigen, aber etwas Einfaches, blockieren Sie den Thread nicht und geben Sie true zurück.
  • Zu guter Letzt können Sie Slice-Autorität zeigen, dies ist der einzige Name, der es dem System erlaubt, Slice auszuführen, siehe Erteilen von Berechtigungen unten.
class MySliceProvider : SliceProvider() {
companion object {
const val SLICE_AUTHORITY = "com.example.android.app.provider"
}
override fun onBindSlice(sliceUri: Uri?): Slice? {
// you can filter the sliceUri here to provide the appropriate slice
return createSlice()
}
override fun onCreateSliceProvider(): Boolean = true}

Die Anwendung muss angeben, welche Klasse für die Bereitstellung von Slices zuständig ist (SliceProvider). Dies geschieht in AndroidManifest wie unten beschrieben.

Beachte das authorities muss mit dem übereinstimmen, was Sie in Ihrem Slice (shortcut.xml) angegeben haben, sowie mit SLICE_AUTHORITY in SliceProvider. Außerdem filtert der Anbieter die Absicht der Kategorie „Slice“.

<application>
...
<provider android:name="MySliceProvider"
android:authorities="com.example.android.app.provider"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.app.slice.category.SLICE" />
</intent-filter>
</provider>

Wie bereits erwähnt, benötigt Google Assistant eine Genehmigung

private fun grantAssistantPermissions() {
getAssistantPackage()?.let { assistantPackage ->
val sliceProviderUri = Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(MySliceProvider.SLICE_AUTHORITY)
.build()

SliceManager.getInstance(this).grantSlicePermission(assistantPackage, sliceProviderUri)
}
}

Durch die Verwendung der bereitgestellten Bausteine ​​(Liste, Kopfzeile, Zeile…). DSL-BeckenSie können schnell Slices erstellen.

// SliceProvider
fun createSlice() {
return list(...) {
header {
title = "My title"
subtitle = "Subtitle"
// Defines the primary action when slice is clicked
primaryAction = SliceAction.create(...)
}
row { ... }
}
}

SliceViewer ist ein Google-Tool, mit dem Sie Slices anzeigen können. Sie können es unten herunterladen und auf Ihr Testgerät oder Ihren Emulator hochladen.

adb install -r -t slice-viewer.apk

Sie können jetzt den folgenden Befehl ausführen, um SliceViewer auszuführen. Achten Sie auf das Schlüsselwort slice hat ein Inhaltspräfix.

adb shell am start -a android.intent.action.VIEW -d 
slice-content://com.example.android.app.provider/slice
ein Beispiel für einen Slice-Viewer

Wir sind mit diesem Teil fertig. Wir haben gelernt, wie man Clips in der App registriert und Google Now zur Verfügung stellt.

Im nächsten Artikel erfahren Sie, wie Sie die Erfahrung noch umfassender gestalten und die Kontrolle über die Anwendung von einem Teil ohne Start kaufen können.

Vollständige Implementierung, Beispiel:

https://github.com/sonique6784/SQLCipherPerformance/commit/1dceced26f07250b41c080ad6e121704eae86ba7

Auspacken der Android-Sicherheit: Teil 1 – Unsachgemäße Nutzung der Plattform Lähde: Ed George | Februar 2022

Ed George
Bildnachweis: Mohn

👋 Hallo und willkommen zu der neuen Reihe von Blogbeiträgen, in denen wir tief in die Android-Sicherheit eintauchen werden. Diese Serie konzentriert sich hauptsächlich auf Top 10 mobil Sicherheitsbedrohungen zu Open Web Application Security Project Foundation (OWASP).die führende Community für Anwendungssicherheit in unserem Bereich.

Während sich diese Posts auf die Android-Plattform konzentrieren, sind viele der Ideen und Gefühle dahinter völlig agnostisch für die Plattform, ebenso wie die OWASP-Top-10-Liste selbst.

Diese Beiträge sind auch eine Ergänzung zu meiner Rede vom Januar 2022 „Don’t Be Stunned by OWASP – An Introduction to Writing Code for Greater Android Security“, in der ich die 5 größten Probleme ausführlicher bespreche. Bitte überprüfen Sie meine Diskussionsseite für weitere Details und relevante Links. EIN begleitender Antrag die die in der Rede vorgestellten Probleme demonstriert, steht ebenfalls zum kostenlosen Download zur Verfügung.

Bitte beachten Sie, dass diese Serie zu Bildungszwecken dient nur. Denken Sie daran, nur Anwendungen zu testen, für die Sie die Erlaubnis dazu haben, und vor allem, sei nicht gemein.

Wenn Ihnen diese Serie gefällt oder Sie Feedback haben, Bitte sende mir eine Nachricht. Danke!

In diesem ersten Teil meiner Serie über Android-Sicherheit werden wir uns mit der Bedrohung Nummer 1 für die Sicherheit mobiler Apps befassen, die von OWASP als unsachgemäße Nutzung der Plattform bezeichnet wird.

Auf den ersten Blick scheint die missbräuchliche Nutzung der Plattform eine etwas vage Aussage über etwas zu sein, das sein sollte das brennendes Problem in der Sicherheit mobiler Anwendungen. Was dieser Titel jedoch subtil auszudrücken versucht, ist, dass die Hauptbedrohung für die Sicherheit unserer mobilen Anwendungen tatsächlich darin besteht uns. Geradeheraus, Wir sind das Problem! ¹

Was meine ich mit dieser hyperbolischen Aussage? Nun, normalerweise führt unbeabsichtigter Missbrauch von Entwicklern, Fahrlässigkeit oder einfach Unverständnis für die Android-Plattform zu unseren schwerwiegendsten Sicherheitsproblemen.

Niemand kann erwarten, dass er die gesamte Plattform von innen kennt, und Entwickler sind auch nicht unfehlbar. Fehler passieren unvermeidlich, aber ich hoffe, dass Sie durch die Einführung einiger der häufigsten Sicherheitsprobleme, die wir versehentlich in unseren Code schreiben, es sich zweimal überlegen, bevor Sie selbst denselben Fehler machen, und sich vor einer potenziellen Sicherheitskatastrophe bewahren.

Entschuldigung für das schreckliche Wortspiel, das erste häufige Beispiel für den Missbrauch der Android-Plattform fällt in die Definition Intent. Für diejenigen, die neu bei Android sind, profitiert die Plattform Intent Klasse als eine Möglichkeit, eine Art von Aktion zu initiieren. Dies kann in Form des Navigierens auf einem neuen Bildschirm in Ihrer App, des Startens eines Hintergrund-/Vordergrund-Dienstes oder der Registrierung eines Rundfunkempfängers erfolgen, um regelmäßige Updates von einer Quelle zu erhalten. Der Intent -Klasse bietet eine einfache Möglichkeit, Daten zu parsen und an separate Anwendungskomponenten zu übergeben, und ist die häufigste Methode, dies mithilfe eines Frameworks zu erreichen.

Allerdings ist das Android-Framework Auch ermöglicht anderen Anwendungen das Senden und Empfangen Intent Instanzen zwischen ihnen, um die „Kommunikation“ zwischen Anwendungen zu erleichtern. Hierin liegt die erste gemeinsame Falle.

Um die Kommunikation zwischen Anwendungen zu ermöglichen, die Komponente der Anwendung, die wir erhalten möchten Intent muss als gekennzeichnet sein android:exported=true Innerhalb AndroidManifest.xml Datei. Wenn Sie eine Komponente mit diesem Flag markieren, können Sie eine „ausdrückliche Absicht“ an eine andere Anwendung (oder ein anderes System) senden, um die angegebene Aktion auszuführen, die die empfangende Komponente verwalten kann.

Darüber hinaus können auch Komponenten definiert werden <intent-filter> Blöcke innerhalb des Manifests, um die Arten von Absichten anzugeben, auf die die Aktivität, der Dienst oder der Broadcast-Empfänger reagieren kann. Durch diese Definition kann eine andere Anwendung „implizite Absicht“ verwenden, um das System aufzufordern, Ihre Anwendung als kompatibel anzuzeigen, wenn sie eine bestimmte Absicht anbietet. Beispielsweise die Weiterleitung an ein implizites Intent-System, um Anwendungen anzuzeigen, die URLs verarbeiten können https://spght.dev kann eine Liste der installierten Webbrowser anbieten. Was jedoch für Anfänger vielleicht nicht offensichtlich ist, ist, dass durch die Angabe des Intent-Filters die Komponente im System als Export gekennzeichnet wird obwohl android:exported=true es ist im Manifest nicht explizit definiert.

Meiner Erfahrung nach ist es nicht ungewöhnlich, dass App-Komponenten versehentlich als „Exportieren“ gekennzeichnet werden, obwohl dies eigentlich nicht der Fall sein sollte. Diese falsch definierten Anwendungskomponenten stellen ein großes Sicherheitsrisiko dar, da sie direkt verfügbar sind und daher potenziell ausgenutzt werden können.

Der Hauptgrund, warum schlecht verwaltete Exporte so gefährlich sind, liegt darin, dass es trivial ist, diese Schwachstellen in der Anwendung zu finden und darauf abzuzielen.

Böswillige Akteure können manuell nach Reverse-Engineering-Anwendungen suchen oder Befehlszeilentools wie z drozer oder Cutter um gefährdete exportierte Komponenten zu scannen. Einmal gesammelt, kann es verwendet werden adb entweder um eine Komponente auszuführen oder um eine Absicht zu erstellen, die die gewünschte Aktion des Hackers ausführt.

Ein bemerkenswertes Beispiel dafür aus der realen Welt wurde vom Käferjäger Mehtab Zafar (mzfr) in seinem November 2020 entdeckt. Blogeintrag die detailliert beschreibt, wie die falsch konfigurierte „Deep-Link-Aktivität“ die Ausnutzung von Multi-Site-Scripting (XSS) auf der offiziellen mobilen GitHub-App ermöglichte. Huch.

Bildnachweis: https://blog.mzfr.me/posts/2020-11-07-exported-activities

U begleitender Antrag für meine Rede geschrieben wurde, wurde dies durch Fehlkonfigurationen von Aktivitäten demonstriert MainActivity dass es gemeldet werden kann, obwohl normalerweise eine “Authentifizierung” für den Zugriff von der Anwendung erforderlich ist.

Wie MainActivity exportiert wird, ist es möglich, einfach anzurufen adb dass das System die Aktivität öffnet und somit die Notwendigkeit einer Authentifizierung umgeht.

All dies mag ein wenig entmutigend klingen, aber zum Glück ist es so einfach, diesen Angriffsvektor zu stoppen, wie die relevanten Komponenten in Ihrem zu sichern AndroidManifest.xml die Datei(en) korrekt mit gekennzeichnet sind android:exported.

Tatsächlich ist es ab Android 12 (API 31) nun eine Anfrage zu setzen android:exported Eigentum an allen Ihren Activity, Serviceich BroadcastReceiver Definitionen in Ihrer Anwendung AndroidManifest.xml Datei(en), wenn Sie auf dieses SDK abzielen.

Als zusätzlichen Schutz ermöglicht die Android-Plattform der App auch, eine „benutzerdefinierte Lizenz“ zu definieren Elemente der Genehmigung im Manifest für Wechselwirkungen einschränken mit seinen exponierten Komponenten.

Beispielsweise kann eine Anwendung eine “Signatur”-Berechtigung definieren, die es ihr erlaubt, nur mit anderen Anwendungen zu interagieren, die dieselbe Berechtigung teilen. ich werden mit demselben Signaturzertifikat erstellt:

Um das Schicksal von GitHub zu vermeiden, ist es außerdem eine bewährte Methode, Inhalte zu überprüfen und zu validieren Intent die Sie erhalten, wenn Sie mit Daten umgehen von a <intent-filter>. Tu es Nein blind glauben, dass das, was Sie bekommen, das sein wird, was Sie erwarten!

In zukünftigen Beiträgen dieser Serie werden wir weitere Fälle von „Plattformmissbrauch“ und mehr als die OWASP Top 10 für mobile Geräte untersuchen.

Danke wie immer fürs Lesen! Ich hoffe, Sie fanden diesen Beitrag interessant, zögern Sie nicht, mich mit Feedback zu twittern @Sp4ghettiCode und vergessen Sie nicht zu klatschen, zu liken, zu twittern, zu teilen, zu markieren usw.

Weiterlesen

Häufige Fehler im Vorstellungsgespräch. Häufige Fehler in Systemdesign-Interviews… | Lähde: Alex Lementuev | Februar 2022

Autor des Fotos Jeremy Bezanger er Unsplash
Alex Lementjew

Liste der Beiträge in dieser Serie:

  • Studieren Sie Open-Source-Projekte – Nicht jedes Projekt ist perfekt, aber Sie können trotzdem viele nützliche Dinge von jedem von ihnen lernen.
  • Ein Blog für Entwickler von Studiofirmen – Sie können viel über ihr grundlegendes technisches Spektrum lernen und über mögliche Fragen nachdenken, die sie stellen könnten.
  • Führe gefälschte Interviews mit deinen Freunden durch – Zeitmanagement ist der Schlüssel: Ihr Ziel ist es, so viel Gelände wie möglich in kürzester Zeit zu bewältigen. Ein wenig Übung baut auch Stress vom Vorstellungsgespräch ab.
  • Systemanforderungen werden nicht erfasst – Die Interviewfrage kann absichtlich unklar sein. Es wird erwartet, dass der Kandidat mehr Fragen stellt, um die Aufgabe besser zu definieren. Weitere Informationen finden Sie unter Sammlungsanforderungen.
  • Ohne klärende Fragen zu stellen – Es kann nützlich sein, einige Informationen über den Zielmarkt, die Zielgruppengröße und Details zum Entwicklerteam zu erhalten.
  • Direkter Übergang zur Umsetzung – Es ist im Allgemeinen ein schlechtes Zeichen, wenn ein Kandidat sofort anfängt, über untergeordnete Themen zu sprechen. Beispielsweise welche Ansichtsklassen verwendet oder welches UI-Architekturmuster angewendet werden soll. Die Details der Implementierung interessieren den Prüfer möglicherweise überhaupt nicht.
  • Stille – Stellen Sie sicher, dass Sie Ihre Lösung besprechen.
  • Warten Sie, bis der Interviewer anfängt, Fragen zu stellen – Wünschenswert ist, dass der Kandidat eine Diskussion “anstößt” (insbesondere bei höherrangigen Kandidaten).

Ein Fehler könnte den Kandidaten aus der Bahn werfen und ihn dazu zwingen, das gesamte Vorstellungsgespräch aufzugeben. Dies ist eine schlechte Strategie, da die meisten Interviewer versuchen, die Fähigkeiten eines Kandidaten einzuschätzen und nicht nur nach “richtigen” Antworten suchen.

  • Lange Einleitung – Tiefer in Ihren beruflichen Hintergrund einzutauchen, gibt nicht viele “Signale”. Der Interviewer würde sich höchstwahrscheinlich eine Meinung bilden, die auf den Ergebnissen des Interviews des Kandidaten basiert und nicht auf einer Zusammenfassung seiner Berufserfahrung.
  • Interviewer ignorieren – Es ist besser, mit dem Sprechen aufzuhören, wenn der Gesprächspartner Sie unterbricht: Versuchen Sie nicht, “den Gedanken zu Ende zu führen” – Es ist besser, zu einem anderen Thema überzugehen und keine Zeit zu verschwenden.
  • ich wiederhole – noch einmal zu den gleichen Dingen: Es gibt dem Prüfer keine zusätzlichen Informationen.
  • Von Thema zu Thema springen – Für den Interviewer kann es schwierig sein, häufige Kontextänderungen zu überwachen.
  • Zu breit mit den Antworten – Das Abdecken irrelevanter Dinge gibt dem Prüfer kein vollständiges “Signal”. Versuchen Sie, bei der Ausgangsfrage zu bleiben.

Die Hauptaufgabe des Interviewers besteht darin, festzustellen, ob der Kandidat für die Stelle geeignet ist. Wenn der Kandidat irgendeine Art von Feindseligkeit von den Interviewern verspürt, sollte dies dem Beschäftigungsspezialisten gemeldet werden.

Am ausgeprägtesten für Kandidaten, die bestimmte Designs online studieren und versuchen, Fragen in eine unabhängige Lösung zu integrieren. Dieser Leitfaden ist eine Reihe von Empfehlungen und definiert kein offizielles Gesprächsprotokoll für irgendein Unternehmen. Der Kandidat sollte sich in jedem konkreten Fall an die Führung der Interviewer halten.

  • Sei zuversichtlich – fester Glaube an eine bestimmte Technologie und Ablehnung jeglicher alternativer Ansätze.
  • Unterbrechung des Interviewers – Der Interviewer könnte einige nützliche Ratschläge geben oder eine Richtung zu einer Lösung vorschlagen. Der Kandidat sollte den Interviewer seinen Gedanken zu Ende führen lassen, bevor er irgendwelche Meinungsverschiedenheiten äußert.
  • „Bildung“ von Interviewern – Wenn der Kandidat der Meinung ist, dass der Interviewer falsch / falsch liegt, ist es besser, dies freundlich vorzuschlagen, anstatt ihm eine Lektion über seine Unwissenheit zu erteilen. Zeit mit der „Bildung“ von Interviewern zu verbringen, gibt kein nützliches „Signal“ und kann einige Warnsignale auslösen.
  • „Erfreulich“ sein – versucht, den Gesprächspartner zu loben, in der Hoffnung auf eine positive Rückmeldung.

Die rote Fahne ist, wenn der Kandidat ohne vorherige Begründung sofort eine konkrete Lösung anbietet. Der Interviewer kann möglicherweise nicht verstehen, warum der Kandidat einen bestimmten Ansatz bevorzugt, ohne ihn mit möglichen Alternativen zu vergleichen.

Es ist riskant, Dinge zu erfinden und darüber zu lügen, da die Möglichkeit besteht, dass der Interviewer ein Experte auf dem Gebiet der Diskussion ist.

Am ausgeprägtesten bei Kandidaten, die sich nicht auf ihre Runde vorbereiten. Das Fehlen eines Lösungsstrukturierungsplans würde während des Gesprächs zusätzlichen Druck ausüben.

Die Verwendung herstellerspezifischer Lösungen während des Interviews betrifft mehr die Details der Implementierung als das Design der Architektur. Der Kandidat kann alle Informationen über den Lieferanten weglassen, es sei denn, der Interviewer fragt ausdrücklich danach.

Manchmal berücksichtigt der Kandidat den “unglücklichen” Weg nicht. Zum Beispiel, wenn der Arbeitsspeicher oder Speicherplatz knapp wird.

Es ist besser zuzugeben, dass Sie nicht wissen, wie die Dinge funktionieren, anstatt Vermutungen anzustellen. Es ist in Ordnung, darüber nachzudenken, wie die Funktionalität bestimmt wird könnten umgesetzt werden, aber Sie müssen zuerst Ihre Unkenntnis angeben.

Der Interviewer ist hier, um Ihnen zu helfen – lassen Sie sich beraten!