Android Tutorial Android Prozesse und Activities Lebensdauer

klaus

Expert
Licensed User
Fangen wir einfach an:
Jedes Basic4android Programm läuft in seinem eigenen Prozess.
Ein Prozess hat einen Hauptthread der auch UI Thread genannt wird und so lange lebt wie der Prozess. Ein Prozess kann auch mehrere Threads haben die für Hintergrundaufgaben nützlich sind.

Ein Prozess startet wenn der Benutzer eine Anwendung startet, angenommen dass sie nicht schon im Hintergrund läuft.

Das Ende eines Prozesses ist weniger ausschlaggebend. Es ereignet sich etwas später nachdem der Benutzer oder das System alle Activities geschlossen hat.
Wenn man zum Beispiel ein Activity offen hat und der Benutzer drückt auf die Back Taste dann wird die Activity geschlossen. Später, falls dem Gerät der freie Speicherplatz zu gering wird (was eventuell vorkommen kann) wird der Prozess zerstört. Wenn der Benutzer das Programm wieder startet, und der Prozess noch nicht zerstört war, wird der gleiche Prozess wieder verwendet.

Eine Basic4android Anwendung besteht aus einem oder mehreren Activities. Android unterstützt aber noch einige andere "Hauptkomponenten". Diese werden in Zukunft in Basic4android hinzu gefügt.

Activities sind den Forms von Windows ähnlich.
Einer der Hauptunterschiede ist dass, wenn eine Activity nicht im Vordergrund ist kann sie zerstört werden um Speicherplatz zu sparen. Man sollte normalerweise den Stand der Activity speichern bevor sie verloren geht. Entweder in einem Dauerspeicher oder in einem Speicher der dem Prozess zugeordnet ist.
Später wird die Activity wieder erstellet wenn sie gebraucht wird.

Ein andere heikler Punkt ist wenn im Gerät eine bedeutende Konfigurationsänderung vorkommt. Die gewöhnlichste ist eine Orientierungsänderung (der Benutzer dreht das Gerät). Wenn so eine Änderung vorkommt werden die laufenden Activities zerstört und dann wieder neu erstellt. Jetzt, wenn die Activity wieder erstellt wird kann man sie an die neue Konfiguration anpassen (zum Beispiel, die Maße des neuen Bildschirms sind bekannt).
Wie macht man das?
Wenn man eine neue Activity erstellt fängt man mit folgender Codevorlage an:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
End Sub
 
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
End Sub
 
Sub Activity_Create(FirstTime As Boolean)
 
End Sub
 
Sub Activity_Resume
 
End Sub
 
Sub Activity_Pause (UserClosed As Boolean)
 
End Sub
Variablen können entweder global oder lokal sein. Lokale Variablen sind Variablen die in Subroutinen ausserhalb 'Sub Process_Globals' und 'Sub Globals' deklariert sind.
Lokale Variablen sind nur im Rahmen der Subroutine gültig in der sie deklariert wurden. Sobald die Subroutine verlassen wird existieren diese Variablen nicht mehr.
Globale Variablen können in allen Subroutinen verwendet werden.

Es gibt zwei Arten von globalen Variablen.
Prozessvariablen und Activityvariablen.

Prozessvariablen – Diese Variablen leben so lange wie der Prozess lebt.
Diese Variablen müssen in der 'Sub Process_Globals' Routine deklariert werden.
Diese Subroutine wird bei jedem Prozesstart aufgerufen (das gilt für alle Activities, nicht nur für die erste Activity).
Nur diese Variablen sind 'öffentliche' Variablen (public variables). Das heisst dass sie auch in anderen Modulen verwendet werden können.
Es können jedoch nicht alle Objektarten als Prozessvariablen deklariert werden.
Zum Beispiel, Views können nicht als Prozessvariablen deklariert werden.
Der Grund dafür ist dass man keine Referenz für Objekte behalten kann die zusammen mit den Activities zerstört werden.
Mit anderen Worten, wenn die Activity zerstört wird, werden alle Views welche die Activity enthält auch zerstört.
Falls wir eine Referenz zu einer View behalten würden, wäre der Garbagecollector (Müllsammler) nicht in der Lage diese Ressourcen frei zu geben und wir würden zu Speichermangel kommen.
Der Compiler unterstützt diese Anforderung.

Activityvariablen – Diese Variablen sind in der Activity begrenzt.
Diese Variablen müssen in der 'Sub Globals' Routine deklariert werden.
Diese Variablen sind "private variables", 'private' Variablen und können nur im laufenden Activitymodul verwendet werden.
Alle Objekttypes können als Activityvariablen deklariert werden.
Jedes mal wenn die Activity erstellt wird, wird die 'Sub Globals' Routine aufgerufen und dies bevor die 'Sub Activity_Create' Routine aufgerufen wird.
Diese Variablen existieren nur solange die Activity existiert.

Sub Activity_Create (FirstTime As Boolean)
Diese Subroutine ist bei jeder Activity Erstellung aufgerufen.
Die Activity wird erstellt wenn der Benutzer die Anwendung startet, die Gerätekonfiguration geändert wurde (der Benutzer dreht das Gerät) und die Activity wurde zerstört, oder wenn die Activity im Hintergrund war und das System sie zerstört hat wegen Speicherplatz Gewinn.
Diese Subroutine benutzt man hauptsächlich zum laden oder erstellen des Layouts (unter anderen Benutzungen).
Der 'FirstTime' Parameter sagt ob die Activity das erste mal erstellt wurde. 'First time' unterliegt dem laufenden Prozess.
Man kann 'FirstTime' für alle Arten von Initialisierungen von Prozessvariablen verwenden.
Zum Beispiel wenn man eine Datei mit einer Liste von Daten hat die man einlesen will, liest man sie wenn 'FirstTime' True ist und speichert die Liste in einer Processvariable.
Jetzt sind wir sicher dass diese Datenliste solange zur Verfügung steht wie der Prozess lebt und es ist nicht nötig die Datenliste wieder zu lesen wenn die Activity neu erstellt wird.

Als Zusammenfassung, man testet ob 'FirstTime' True ist, und initialisiert alle Prozessvariablen.

Sub Activity_Resume und Sub Activity_Pause (UserClosed As Boolean)
Jedes mal wenn sich die Activity vom Vordergrund in den Hintergrund bewegt, wird die 'Sub Activity_Pause ' Routine angerufen.
'Sub Activity_Pause' wird auch aufgerufen wenn die Activity im Vordergrund ist und eine Konfigurationänderung vorkommt (das führt dazu das die Activity auf 'Pause' gestellt und nachher zerstört wird).
'Sub Activity_Pause' ist die letzte Stelle an der man wichtige Informationen speichern kann.
Allgemein gibt es zwei Mechanismen zum Sichern der Activity Parameter.
Informationen die nur für die laufende Anwendung relevant sind können in eine oder mehrere Prozessvariablen gespeichert werden.
Andere Informationen müssen in einem Dauerspeicher gesichert werden (Datei oder Datenbank).
Zum Beispiel, falls der Benutzer Konfigurationsparameter geändert hat müssen diese hier gesichert werden. Ansonsten gehen diese Daten verloren.

'Sub Activity_Resume' wird direkt nachdem 'Sub Activity_Create' endet aufgerufen, oder wenn eine Activity von Pause zurück kommt (wenn eine Activity in den Hintergrund bewegt wurde und wieder in den Vordergrund hervor gerufen wird).
Wenn man eine andere Activity mit StartActivity aufruft, wird die laufende Activity zuerst auf Pause gestellt und dann wird die andere Activity erstellt (wenn nötig), und 'Sub Activity_Resume' wird immer aufgerufen.

Wie oben beschrieben, wird 'Sub Activity_Pause' jedes mal aufgerufen wenn die Activity vom Vordergrund in den Hintergrund bewegt wird.
Das kommt vor wenn:
1. Eine andere Activity gestartet wird.
2. Die 'Home' Taste gedrückt wurde.
3. Ein Konfigurationsänderungsevent gefeuert wurde (Orientierungsänderung zum Beispiel).
4. Die 'Back' Taste gedrückt wurde.

In den Fällen 1 und 2, wird die Activity auf Pause gestellt und bleibt im Speicher da sie voraussichtlich wieder benutzt wird.
In Fall 3 wird die Activity auf Pause gestellt, zerstört und dann wieder neu erstellt (und resumed).
In Fall 4 wird die Activity auf Pause gestellt und zerstört. Ein Drücken auf die 'Back'
Taste ist dem Schliessen der Activity gleich. In diesem Fall ist es nicht nötig irgend welche spezifische Instanzinformationen zu speichern (zum Beispiel, der Standpunkt von Pacman in einem PacMan Spiel).
Der 'UserClosed' Parameter ist in diesem Fall True und in allen anderen Fällen False. Er ist auch True wenn man die 'Sub Activity.Finish' Routine aufruft. Diese Funktion stellt die Activity auch auf Pause und zerstört sie, ähnlich wie mit der 'Back' Taste.

Man kann den 'UserClosed' Parameter benutzen um zu entscheiden welche Daten gespeichert werden sollen und auch welche Prozessvariablen auf ihren Uhrsprungswert gesetzt werden sollen (zum Beispliel, die Pacman Stellung in die Mitte setzen falls die Stellung eine Prozessvariable ist).
 
Last edited:

KurtS

Member
Licensed User
Ich bewundere Ihre Arbeit und bin dankbar für die unschätzbare Hilfe zum Verstehen der Zusammenhänge.

Darf ich mir dennoch erlauben, Sie auf einen permamenten Fehler hizuweisen?

Vordergrund schreibt man mit V und nicht mit F. Bitte nicht sauer sein!
 

AppMessias

New Member
Licensed User
Danke Klaus

Hallo Klaus,
ich habe diese Woche mir Basic4Android gekauft und bin nun seit 3 h ca. am Programmieren auf meinem LG Optimus Speed Handy und mich bedanken für Deine deutschen Erläuterungen. Es macht Spass und ist eine Klasse IDE.
Danke muss man auch mal sagen.
Gruss Friedrich
 

christianK

Member
Licensed User
tabelle v0.3

hallo,

für anfänger wie mich selbst hier mal eine tabelle, wann welche reihenfolge von b4a "abgearbeitet" wird. danke an klaus für die berichtigungen.

1.
die anwendung ist neu auf dem telefon und wird zum ersten mal ausgeführt.


- keine der variablen ist gedimt
- keine variable hat einen inhalt
- es wird der reihe nach ausgeführt:
- Process_Globals, um programmweite variablen zu dimmen
- Globals, um activityweite variablen zu dimmen
- Activity_Create
- FirstTime ist true
- Activity_Resume




2.
die anwendung wird zum erneut ausgeführt, nachdem 2.1 das telefon neu gestartet wurde oder 2.2 die anwendung lange zeit in der pause war und von android zerstört wurde.

wie 1.


3.
während der anwendung wird die "home"-taste gedrückt.


- Activity_Pause wird ausgeführt
- UserClosed ist false
- die anwendung geht in den pausemodus
- die anwendung bleibt pausiert, kann aber von android zerstört werden
- alle variablen verlieren ihren inhalt, sobald die anwendung zerstört wird


4.
während der anwendung wird die "zurück"-taste gedrückt.


- Activity_Pause wird ausgeführt
- UserClosed ist true
- alle globale Variablen verlieren ihren Inhalt
- alle Process globale Variablen behalten ihren Inhalt solange die Anwndung nicht zerstört wurde
- die Anwendung bleibt pausiert, kann aber von Android zerstört werden



5.1
die anwendung wird gestartet, wärend sie durch 3. Home pausiert war, aber noch nicht zerstört wurde.

- Activity_Resume wird ausgeführt
- alle Variablen behalten ihren Inhalt
- das letzte geladene Layout wird angezeigt
- alle User-Eingaben in dem Layout (textboxen, auswahlen..) behalten ihren Inhalt
- ob Fall 3. oder Fall 4. eingetreten ist, kann der Programmierer mit einer Process globalen Variable behandeln


5.2
die anwendung wird gestartet, wärend sie durch 4. Back pausiert war, aber noch nicht zerstört wurde.

- Globals wird ausgeführt
- Activity_Create wird ausgeführt
- Activity_Resume wird ausgeführt
- Process globale Variablen behalten ihren Inhalt
- Globale Variablen sind neu gedimt und haben den default Inhalt,
- das erste Layout wird angezeigt
- alle User-Eingaben in dem Layout (textboxen, auswahlen..) sind verschwunden
- ob Fall 3. oder Fall 4. eingetreten ist, kann der Programmierer mit einer Process globalen Variable behandeln


6.
von der haupt-activity wird eine andere ("tochter")-activity aufgerufen


- bei der haupt-activity: Activity_Pause wird ausgeführt
- UserClosed ist false
- alle variablen der hauptactivity bleiben ihr erhalten
- der tochteractivity stehen die variablen aus Sub Process_Globals zur verfügung.
- der tochteractivity stehen die variablen aus Sub Globals nicht zur verfügung.
- bei der tochteractivity wird Process_Globals nicht ausgeführt
- bei der tochteractivity wird Globals ausgeführt
- bei der tochteractivity wird Activity_Create ausgeführt
- FirstTime ist false
- bei der tochteractivity wird Activity_Resume ausgeführt


7.
bei einer tochteractivity wird der zurück-knopf gedrückt


- bei der tochter wird Activity_Pause ausgeführt
- bei der hauptactivity wird Activity_Resume ausgeführt




8.
bei einer tochteractivity wird der home-knopf gedrückt

- Gleich wie 5.1 mit der aktuellen Activity


9.
bei einer laufenden activity wird mit
B4X:
Activity.LoadLayout("layoutname")
ein anderes layout geladen


- beide layouts werden übereinander und gleichzeitig dargestellt, sonst passiert nix

10.
bei einer laufenden activity wird mit
B4X:
For i=Activity.NumberOfViews-1 To 0 Step -1
  Activity.RemoveViewAt(i) 
Next
das aktuelle layout gelöscht und mit
B4X:
Activity.LoadLayout("layoutname")
ein anderes layout geladen





- alle Variablen sind gedimt
- alle Variableninhalte stehen noch zur verfügung
- alle Usereingaben aus dem ursprüngllichen Layout sind bei wiederladen weg

 
Last edited:

klaus

Expert
Licensed User
Einige Korrekturen:

3. während der Anwendung wird die "Home"-taste gedrückt.
- Activity_Pause wird ausgeführt
- UserClosed ist false
- alle Variablen verlieren ihren Inhalt, nur wenn die Anwendung zerstört wurde
- die Anwendung bleibt pausiert, kann aber von Android zerstört werden

4. während der Anwendung wird die "Back"-taste gedrückt.
- Activity_Pause wird ausgeführt
- UserClosed ist true
- alle globale Variablen verlieren ihren Inhalt

- alle Process globale Variablen behalten ihren Inhalt solange die Anwndung nicht zerstört wurde
- die Anwendung bleibt pausiert, kann aber von Android zerstört werden

5.1 die anwendung wird gestartet, wärend sie durch 3. Home pausiert war, aber noch nicht zerstört wurde.
- Activity_Resume wird ausgeführt
- alle Variablen behalten ihren Inhalt
- das letzte geladene Layout wird angezeigt
- alle User-Eingaben in dem Layout (textboxen, auswahlen..)
behalten ihren Inhalt
- ob Fall 3. oder Fall 4. eingetreten ist, kann der Programmierer mit einer Process globalen Variable behandeln


5.2 die anwendung wird gestartet, wärend sie durch 4. Back pausiert war, aber noch nicht zerstört wurde.
- Globals wird ausgeführt
- Activity_Create wird ausgeführt
- Activity_Resume wird ausgeführt
- Process globale Variablen behalten ihren Inhalt
- Globale Variablen
sind neu gedimt und haben den default Inhalt,
- das erste Layout wird angezeigt
- alle User-Eingaben in dem Layout (textboxen, auswahlen..) sind verschwunden
- ob Fall 3. oder Fall 4.
eingetreten ist, kann der Programmierer mit einer Process globalen Variable behandeln

8. bei einer Tochteractivity wird der Home-Knopf gedrückt
- Gleich wie 5.1 mit der aktuellen Activity

10. bei einer laufenden Activity wird mit
B4X:
Activity.RemoveAllViews
das aktuelle Layout gelöscht und mit
B4X:
Activity.LoadLayout("layoutname")
ein anderes Layout geladen

- alle Variablen sind gedimt
- alle Variableninhalte stehen noch zur verfügung
- alle Usereingaben aus dem ursprüngllichen Layout sind bei wiederladen weg

Beste Grüsse.
 

ziwalig

Member
Licensed User
Activity_Pause wird nicht durchlaufen

Hallo Klaus

Auch ich möchte mich als erstes bei dir und allen anderen hier bedanken für die hervorragende Arbeit in dieser Community.

Ich habe mit Activity_Pause ein Problem.

ChristianK schreibt unter „7. bei einer tochteractivity wird der zurück-knopf gedrücktdass“ das Activity_Pause ausgeführt wird. In meinem Projekt wird Activity_Pause nicht ausgeführt.

Ich habe auch das Beispiel „TwoActivities“ herunter geladen und ausprobiert. Auch hier wird bei der zweiten Activity nach drücken der Zurück Taste keine Actiwity_Pause ausgeführt.

Ich möchte nach dem betätigen der Zurück Taste die Activity zerstören damit sicher keine Leichen zurück bleiben. Kannst du mir ein Tipp geben warum das so ist und wie ich es ändern kann?

Grüsse
Ziwalig
 

klaus

Expert
Licensed User
Hallo ziwalig,

Willkommen im Forum !

Zwei Fragen:
- Wie und was hast Du getestet um ausagen zu können dass Activity_Pause nicht durchgeführt wird ?
Breakpoints funktionieren nicht in Activity_Pause !

- Von welcher Activity_Pause Routine sprichst Du. Von der Activity_Pause Routine in der zweiten Activity oder von der Hauptactivity ?

Schreibe folgende Zeile in beide Activity_Pause Routinen:
B4X:
Log("Pause")
und schaue im Log Tab da wist Du sehen dass "Pause" geschrieben wird.

Beste Grüsse.
 

ziwalig

Member
Licensed User
Hallo Klaus

Ich muss mich für die etwas voreilige Behauptung entschuldigen.

Der Log funktioniert und sicher auch andere Befehle. Mein schnelltest war in der zweiten Activity eine Msgbox und diese funktioniert nicht. Weil ich aber einen Programmierfehler hatte dachte ich dass auch Activity.Finish nicht funktioniert.

Nochmals Sorry für diese Behauptung :sign0013:

Grüsse
Ziwalig
 

xray12frank

Member
Licensed User
Hilfe bin überfordert

Hallo Klaus,

habe nun schon viel gelesen und bin seit kurzem auch registriert. Habe auch eine Vollversion erworben und bin bis jetzt total begeistert.

Leider finde ich den Einstieg in's Forum recht schwierig..war bisher immer Einzelkämpfer und nicht der grosse Forenfreak (Sorry)

Gibt's einen Link im Forum wo so absolute Newbies auch mal hinfinden?

Dann das nächste..habe schon ein paar "Miniprogramme" geschrieben und auf meinem S2 stolz installiert. Leider heissen die alle B4A.EXAMPLE kann machen was ich will.

Sorry Leutz ich weis, das ist hier nicht der richtige Thread..aber ich bin lernwillig. DANKE im Voraus. Frank
 

klaus

Expert
Licensed User
Hallo Frank,

Willkommen im Forum.

Ich kann Dir nur folgendes vorschlagen (leider immer noch lesen):
- Ratschläge zum Anfangen und Fragen stellen

Da steht so ungefähr Alles zum Anfangen drin.

Bitte für neue Fragen jedes mal einen neuen Thread erstellen.
Klicke auf German Forum und dann oben links auf New Thread.

Beste Grüsse.
 
Top