Auf dieser Seite werden wichtige Aspekte des Testens von Apps mit mehreren Nutzern auf der Android-Plattform beschrieben. Informationen zur Implementierung der Unterstützung mehrerer Nutzer finden Sie unter Mehrere Nutzer unterstützen.
Gerätepfade
In der folgenden Tabelle sind einige der Gerätepfade und die Art ihrer Auflösung aufgeführt. Alle Werte in der Spalte Pfad sind ein nutzerspezifischer Sandbox-Speicher. Die Speichersituation unter Android hat sich im Laufe der Zeit geändert. Weitere Informationen finden Sie in der Dokumentation zum Thema Speicher.
Pfad | Systempfad (optional) | Zweck |
---|---|---|
/data/user/{userId}/{app.path}
|
/data/data
|
App-Speicher |
/storage/emulated/{userId}
|
/sdcard
|
Gemeinsam genutzter interner Speicher |
/data/media/{userId}
|
Keine | Nutzer-Medieninhalte (z. B. Musik, Videos) |
/data/system/users/{userId}
|
Keine | Systemkonfiguration/Status pro Nutzer
Nur für System-Apps zugänglich |
Hier ein Beispiel für die Verwendung eines nutzerspezifischen Pfads:
# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/
adb-Interaktionen zwischen Nutzern
Mehrere adb
-Befehle sind nützlich, wenn Sie es mit mehreren Nutzern zu tun haben. Einige dieser Befehle werden nur unter Android 9 und höher unterstützt:
adb shell am instrument --user <userId>
führt einen Instrumentierungstest für einen bestimmten Nutzer aus. Standardmäßig wird der aktuelle Nutzer verwendet.- Mit
adb install --user <userId>
wird ein Paket für einen bestimmten Nutzer installiert. Damit ein Paket für alle Nutzer installiert wird, müssen Sie diese Funktion für jeden Nutzer aufrufen. - Mit
adb uninstall --user <userId>
wird ein Paket für einen bestimmten Nutzer deinstalliert. Rufen Sie die Funktion ohne das Flag--user
auf, um die App für alle Nutzer zu deinstallieren. adb shell am get-current-user
ruft die aktuelle (Vordergrund-)Nutzer-ID ab.adb shell pm list users
ruft eine Liste aller vorhandenen Nutzer ab.- Mit
adb shell pm create-user
wird ein neuer Nutzer erstellt und die ID zurückgegeben. - Mit
adb shell pm remove-user
wird ein bestimmter Nutzer anhand der ID entfernt. - Mit
adb shell pm disable --user <userId>
wird ein Paket für einen bestimmten Nutzer deaktiviert. - Mit
adb shell pm enable --user <userId>
wird ein Paket für einen bestimmten Nutzer aktiviert. adb shell pm list packages --user <userId>
listet Pakete (-e
für aktiviert,-d
für deaktiviert) für einen bestimmten Nutzer auf. Standardmäßig werden immer Listen für den Systemnutzer angezeigt.
Die folgenden Informationen helfen Ihnen, das Verhalten von adb
bei mehreren Nutzern zu verstehen:
adb
(oder genauer gesagt deradbd
-Daemon) wird immer als Systemnutzer (Nutzer-ID = 0) ausgeführt, unabhängig davon, welcher Nutzer gerade aktiv ist. Daher werden gerätebezogene Pfade, die nutzerabhängig sind (z. B./sdcard/
), immer als Systemnutzer aufgelöst. Weitere Informationen finden Sie unter Gerätepfade.Wenn kein Standardnutzer angegeben ist, hat jeder
adb
-Unterbefehl einen anderen Nutzer. Es hat sich bewährt, die Nutzer-ID mitam get-current-user
abzurufen und dann--user <userId>
explizit für alle Befehle zu verwenden, die sie unterstützen. Bis Android 9 wurden explizite Nutzer-Flags nicht für alle Befehle unterstützt.Ab Android 9 wird der Zugriff auf
/sdcard
-Pfade von sekundären Nutzern verweigert. Weitere Informationen zum Abrufen von Dateien während des Testens finden Sie unter Contentanbieter für Daten für mehrere Nutzer.
Contentanbieter für Daten von mehreren Nutzern
Da adb
als Systemnutzer ausgeführt wird und Daten in Android 9 und höher in einer Sandbox gespeichert werden, müssen Sie Content-Provider verwenden, um Testdaten von einem Nicht-Systemnutzer zu übertragen. Dies ist nicht erforderlich, wenn:
adbd
wird als Root ausgeführt (überadb root
), was nur mituserdebug
- oderusereng
-Builds möglich ist.Sie verwenden
ITestDevice
von Trade Federation (Tradefed), um die Dateien zu übertragen. In diesem Fall verwenden Sie/sdcard/
-Pfade in Ihrer Testkonfiguration (siehe z. B. den Quellcode fürpushFile
inNativeDevice.java
).
Wenn ein Contentanbieter im sekundären Nutzer ausgeführt wird, können Sie darauf zugreifen, indem Sie den Befehl adb shell content
mit den entsprechenden Parametern user
, uri
und anderen Parametern ausführen.
Problemumgehung für App-Entwickler
Verwenden Sie für die Interaktion mit Testdateien adb content
und eine Instanz von ContentProvider
anstelle des Befehls push
oder pull
.
- Erstellen Sie eine Instanz von
ContentProvider
, die von der App gehostet wird und Dateien bei Bedarf bereitstellen und speichern kann. Den internen Speicher der App verwenden - Verwenden Sie die Befehle
adb shell content
read
oderwrite
, um die Dateien zu übertragen.
Problemumgehung für Mediendateien
Wenn Sie Mediendateien auf die Medienpartition der SD-Karte übertragen möchten, verwenden Sie die öffentlichen APIs von MediaStore
. Beispiel:
# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg
# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"
# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg
Allgemeinen Contentanbieter installieren
Installieren und verwenden Sie einen vorhandenen Contentanbieter, der Dateien in den nutzerspezifischen Pfad /sdcard
liest und schreibt.
Erstellen Sie TradefedContentProvider.apk
aus der Quelle mit make TradefedContentProvider
:
```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk
# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt
# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```
Unterstützung mehrerer Nutzer in Trade Federation
Tradefed ist das offizielle Android-Test-Framework. In diesem Abschnitt wird die integrierte Unterstützung von Tradefed für Testläufe mit mehreren Nutzern zusammengefasst.
Statusprüfer
Systemstatusprüfungen (System Status Checkers, SSCs) werden vor den Zielvorbereitern ausgeführt und ihre Bereinigung erfolgt nach diesen Vorbereitern.
UserChecker
wird explizit definiert, um Entwicklern beim Testen mehrerer Nutzer zu helfen. Es wird erfasst, ob durch einen Test der Status der Nutzer auf dem Gerät geändert wurde (z. B. ob Nutzer erstellt wurden, ohne sie im Teardown zu entfernen). Wenn user-cleanup
festgelegt ist, wird außerdem automatisch versucht, nach dem Test aufzuräumen. Gleichzeitig werden hilfreiche Fehler ausgegeben, damit der Test behoben werden kann.
<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
<option name="user-cleanup" value="true" />
</system_checker>
Zielvorbereiter
Zielvorbereiter werden in der Regel verwendet, um ein Gerät mit einer bestimmten Konfiguration einzurichten. Bei Tests mit mehreren Nutzern können mit Preparers Nutzer eines bestimmten Typs erstellt und zu anderen Nutzern gewechselt werden.
Bei Gerätetypen, die keinen sekundären Nutzer haben, können Sie mit CreateUserPreparer
einen sekundären Nutzer in AndroidTest.xml
erstellen und zu ihm wechseln. Am Ende des Tests wechselt der Vorbereiter zurück und löscht den sekundären Nutzer.
<target_preparer
class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>
Wenn der gewünschte Nutzertyp bereits auf dem Gerät vorhanden ist, verwenden Sie SwitchUserTargetPreparer
, um zum vorhandenen Nutzer zu wechseln. Häufige Werte für user-type
sind system
oder secondary
.
<target_preparer
class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
<option name="user-type" value="secondary" />
</target_preparer>
Hostgesteuerte Tests
In einigen Fällen muss bei einem Test innerhalb des Tests der Nutzer gewechselt werden. Nehmen Sie den Wechsel nicht über ein geräteseitiges Testframework wie UI Automator vor, da der Testprozess jederzeit beendet werden kann. Verwenden Sie stattdessen ein hostseitiges Test-Framework wie das Host-driven test framework von Tradefed, das Zugriff auf ITestDevice
bietet und alle erforderlichen Nutzermanipulationen ermöglicht.
Verwenden Sie UserChecker
(siehe Statusprüfungen) für hostgesteuerte Tests, bei denen sich der Nutzerstatus ändert, da so sichergestellt wird, dass der Test nach Abschluss ordnungsgemäß bereinigt wird.