Apps korrekt beenden - das warum und wie ..

  • Antworten:52
  • OffenNicht stickyNicht beantwortet
Gelöschter Account
  • Forum-Beiträge: 694

11.09.2012, 15:08:08 via Website

Kleine Korrektur: onResume sowie onPause sind das richtige Pärchen. onStart/onStop brauchst Du normalerweise nie.

Die Activity ist außerhalb onResume/onPause nicht sichtbar. BroadcastReceiver z.B. außerhalb der beiden sind sinnlos da sie entweder Töne oder Bildschirmausgaben produzieren. Wer will das schon von einer nicht mehr sichtbaren Activity.

Antworten
  • Forum-Beiträge: 77

11.09.2012, 15:11:07 via Website

Frank Mehlhop
Ich habe noch nie mit Flag's gearbeitet.
Ich vermute, das ginge auch mit onPause() statt mit onStop()?!?
Weil wenn onStop() greift, dann habe ich das Problem ja schon gar nicht mehr.

Das hört sich sehr merkwürdig an. onPause() wird aufgerufen, wenn eine andere App den Focus erhält, aber deine App noch auf dem Bildschirm sichtbar ist. In dem Fall wäre wohl sinnvoll, wenn die Sounds noch abgespielt werden.
Wenn du den Home Button drückst, wird IMMER auch onStop() aufgerufen.

Aus deinen Posts würde ich mal herauslesen, dass du in deiner App den Activity Lifecycle nicht korrekt umsetzt. Vielleicht mal hier nachlesen: http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Frank M.

Antworten
  • Forum-Beiträge: 77

11.09.2012, 15:12:15 via Website

Harald Wilhelm
Die Activity ist außerhalb onResume/onPause nicht sichtbar. BroadcastReceiver z.B. außerhalb der beiden sind sinnlos da sie entweder Töne oder Bildschirmausgaben produzieren. Wer will das schon von einer nicht mehr sichtbaren Activity.

Das stimmt so nicht.

"If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.

If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere."

http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

— geändert am 11.09.2012, 15:19:20

Antworten
  • Forum-Beiträge: 284

11.09.2012, 15:21:11 via Website

Frank Mehlhop
André
die "gegeben Anlässe" sind vermutlich Events die per BroadcastReceiver empfangen werden? Die solltest du eh in onStop() deaktivieren.

Ne, es sind Sensordaten, die akustisch ausgewertet werden.

Ob die Daten nun per BroadcastReceiver empfangen oder eine Sensor direkt in der App ausgelesen wird, letztendlich kann man beides in der onPause() /onStop() abstellen bzw. ab/-unterbrechen

Lange Rede kurzer Sinn, man kann den Home-Button nicht wirklich überschreiben.

— geändert am 11.09.2012, 15:22:35

Frank M.

Antworten
  • Forum-Beiträge: 20

11.09.2012, 15:23:06 via Website

Kann ich innerhalb des Programms herauslesen,
ob die App im onPause()-Modus (gar im onStop()-Modus) ist oder nicht?

Antworten
  • Forum-Beiträge: 77

11.09.2012, 15:25:28 via Website

Frank Mehlhop
Kann ich innerhalb des Programms herauslesen,
ob die App im onPause()-Modus (gar im onStop()-Modus) ist oder nicht?

Das kannst du dir einfach merken. Aber wie gesagt, das wäre nur ein workaround, das eigentliche Problem ist dass du den Acivity Lifecycle missachtest.

Vermutlich liest du die Sensordaten in einem Thread per Timer aus, und wenn du das nicht stoppst, wenn deine App in den Hintergrund kommt (onStop()), wird man sie ganz schnell wieder deinstallieren. Nicht wegen der Töne, sondern weil sie dann unnötig Batterie frisst.

— geändert am 11.09.2012, 15:26:51

Antworten
  • Forum-Beiträge: 20

11.09.2012, 15:37:39 via Website

André
Das kannst du dir einfach merken.
...meinst Du ich merke mir ob die App auf onPause() steht, oder was?
(mit Flag's...?!)

André
Vermutlich liest du die Sensordaten in einem Thread per Timer aus,
Nein, ich lese die Sensordaten per Listener aus.

André
und wenn du das nicht stoppst, wenn deine App in den Hintergrund kommt (onStop()), ...
Na das ist doch genau das Thema!
Die App ist am laufen und der User will mit Home beenden.
S'is aber nicht beendet, sondern der Thread läuft weiter
und das will ich vermeiden.

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

11.09.2012, 15:40:32 via Website

André
Das stimmt so nicht.

Dann ist halt diese Android Developer Seite falsch.

"onPause() is where you deal with the user leaving your activity."

Wie auch immer, ich habe in keiner meiner Anwendungen onStop()/onStart() in Benutzung und halte mich seit Jahren an die o.a. Regeln.

Ich wollte das gerade noch mit den SDK Samples unterfüttern und bin direkt beim ersten Sample (MapsDemo) über folgendes gestolpert - da ist dann jegliche Argumentation für die Katz ;-)

1@Override
2 protected void onResume() {
3 super.onResume();
4 mSensorManager.registerListener(mRotateView,
5 SensorManager.SENSOR_ORIENTATION,
6 SensorManager.SENSOR_DELAY_UI);
7 mMyLocationOverlay.enableMyLocation();
8 }
9
10 @Override
11 protected void onStop() {
12 mSensorManager.unregisterListener(mRotateView);
13 mMyLocationOverlay.disableMyLocation();
14 super.onStop();
15 }

Antworten
  • Forum-Beiträge: 77

11.09.2012, 15:52:16 via Website

Das sind halt auch nur Menschen bei Google ;)

Harald Wilhelm
Dann ist halt diese Android Developer Seite falsch.

"onPause() is where you deal with the user leaving your activity."

EDIT: das widerspricht dem Rest nicht. Der Benutzer verlässt die Activity, sie ist aber noch sichtbar.

Tatsächlich ist mir in der Praxis aber kein Fall bekannt, wo die App nicht mehr den Focus hat, aber noch sichtbar ist. Sowas wie ein Popup Fenster des Systems gibt es ja bei Android eigentlich nicht. (Lustigerweise lässt der Aufruf des Task-Managers die App nicht pausieren.)
Von daher sollte es in der Praxis wohl egal sein, ob man sich an onPause() oder onStop() ranhängt, da eh immer beides direkt nacheinander aufgerufen wird.

Die Idee im Lifecycle wäre aber eher, dass man in onPause() z.B. ein Spiel anhält (der Benutzer macht ja gerade was anderes), aber noch ausgibt (es ist ja noch (teilweise) sichtbar). Erst in onStop() ist die App dann wirklich nicht mehr zu sehen und man sollte sie stilllegen.

Ich habe grad den GLSurfaceView.Renderer angeschaut, der reagiert auch auf pause/resume. Das ist wohl alles noch nicht so ausgereift.

— geändert am 11.09.2012, 15:57:21

Antworten
  • Forum-Beiträge: 77

11.09.2012, 15:55:32 via Website

Frank Mehlhop
Na das ist doch genau das Thema!
Die App ist am laufen und der User will mit Home beenden.
S'is aber nicht beendet, sondern der Thread läuft weiter
und das will ich vermeiden.

Genau darum geht's. Einfach in onStop() den Listener stoppen (unregisterReceiver() oder whatever), dann tut die App nichts wenn sie nicht sichtbar ist und alle sind glücklich. (Vorausgesetzt das Registrieren des Listeners passiert in onStart(), was auch jetzt schon so sein sollte.)

Die Funktion des Home-Button zu überschreiben wäre auch ziemlicher Müll. Und ist in keiner Situation nötig, außer man will einen zusätzlichen Button für seine Anwendung gewinnen ;)

Antworten
  • Forum-Beiträge: 20

11.09.2012, 16:51:47 via Website

uih,...
da hatte ich ne lange Leitung
1protected void onPause() {
2 finish();
3 System.exit(0);
4 }
...tut, was es soll. :grin:

und System.exit(0); ist wichtig, sonst gibt es eine überflüssige Extrameldung, dass die App gestoppt wurde.

Interessant finde ich übrigens noch, dass wenn ich in "Apps verwalten" gehe und meine App anwähle der Button "Stoppen erzwingen" immer noch aktiv ist. Das tut nicht weh, aber ich hätte erwartet, das die App gestoppt ist.

Antworten
  • Forum-Beiträge: 77

11.09.2012, 17:01:46 via Website

Viele Wege führen nach Rom. Deiner ist unsauber, aber funktioniert.
Du darfst dich dann nicht über Seiteneffekte wundern, z.B. wenn du deine App aus einer anderen heraus startest.

— geändert am 11.09.2012, 17:01:55

Antworten
  • Forum-Beiträge: 20

11.09.2012, 17:17:54 via Website

Hi André!

André
Viele Wege ...Deiner ist unsauber

Nun gut, will ja nicht gerne dreckig werden. ;)

Ich habe ein bissl rumprobiert mit unregisterReceiver() .
Du meinst doch, dass damit eine sauber Lösung möglich sei?!

Aber so richtig komme ich damit nicht zu Potte.
Ich benötige doch keinen BroadcastReceiver,
wozu also unregisterReceiver()?

Frank

Antworten

Empfohlene Artikel