android wikipedia - Ist das Beenden einer Anwendung verpönt?




aktuelle version (25)

In meinem Versuch, Android zu lernen, lese ich gerade folgendes :

Frage: Hat der Benutzer die Wahl, die Anwendung zu beenden, es sei denn, wir setzen eine Menüoption, um sie zu beenden? Wenn keine solche Option existiert, wie beendet der Benutzer die Anwendung?

Antwort: (Romain Guy): Der Benutzer nicht, das System handhabt dies automatisch. Dies ist der Aktivitätslebenszyklus (insbesondere onPause / onStop / onDestroy). Egal, was Sie tun, setzen Sie keine "Beenden" oder "Beenden" -Anwendung Schaltfläche. Es ist nutzlos mit Androids Anwendungsmodell. Dies steht auch im Widerspruch zur Funktionsweise von Kernanwendungen.

Hehe, bei jedem Schritt in der Android-Welt stoße ich auf ein Problem = (

Anscheinend können Sie eine Anwendung in Android nicht beenden (aber das Android-System kann Ihre App völlig zerstören, wann immer es sich anfühlt). Was ist damit? Ich fange an zu denken, dass es unmöglich ist, eine App zu schreiben, die als "normale App" funktioniert - dass der Nutzer die App beenden kann, wenn er sich dazu entschließt. Das sollte nicht auf das Betriebssystem angewiesen sein.

Die Anwendung, die ich erstellen möchte, ist keine Anwendung für den Android Market. Es ist keine Anwendung für "breite Nutzung" durch die breite Öffentlichkeit, es ist eine Business-App, die in einem sehr engen Geschäftsfeld eingesetzt wird.

Ich habe mich wirklich sehr darauf gefreut, für die Android-Plattform zu entwickeln, da es viele Probleme behebt, die in Windows Mobile und .NET existieren. Aber die letzte Woche war für mich eine kleine Ablenkung ... Ich hoffe, ich muss Android nicht aufgeben, aber es sieht jetzt nicht sehr gut aus = (

Gibt es eine Möglichkeit für mich, die Bewerbung wirklich zu beenden?


Answers

As an Application in an Android context is just a bunch of vaguely related Activities, quitting an Application doesn't really make much sense. You can finish() an Activity, and the view of the previous Activity in the Activity stack will be drawn.


I think the point is that there is no need to quit the app unless you have buggy software. Android quits the app when the user is not using it and the device needs more memory. If you have an app that needs to run a service in the background, you will likely want a way to turn the service off.

For example, Google Listen continues to play podcast when the app is not visible. But there is always the pause button to turn the podcast off when the user is done with it. If I remember correctly, Listen, even puts a shortcut in the notification bar so you can always get to the pause button quickly. Another example is an app like a twitter app for instance which constantly polls a service on the internet. These types of apps should really allow the user to choose how often to poll the server, or whether even to poll in a background thread.

If you need to have code that runs on exit, you can override onPause(), onStop(), or onDestroy() as appropriate. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle


Answer: (Romain Guy): The user doesn't, the system handles this automatically. That's what the activity lifecycle (especially onPause/onStop/onDestroy) is for. No matter what you do, do not put a "quit" or "exit" application button. It is useless with Android's application model. This is also contrary to how core applications work.

1: Totally exiting an application may be generally unmandatory, but it is not useless. What if windows had no exit option? System would be doggy slow as memory was full and the OS had to guess at which programs you were done with. I don't care what Romain Guy or even Larry Page and Sergey Brin say - these are unquestionable facts: Systems run slower when they have to kill tasks to get their memory before a new app can be launched. You just can't tell me that it doesn't take time to kill an app! Even the light from distant stars take time... There is some use in allowing the user to fully close apps.

2: Contrary to how core applications work? What's that supposed to mean? When I'm done running an app for now, it is no longer doing any work...It's just waiting to be killed by the OS when its memory is needed.

In summary, there is a distinct difference between minimizing and exiting, and neither pinch hits well for the other. Do we leave a screwdriver in every screw? Or a key in every door? Do we leave all of our appliances on high until the breaker blows and we need to turn on another appliance? Do we leave the dish washer full of dishes, and only take out enough each time to make room for some new dirty ones? Do we leave all the cars running in the driveway until -- oh never mind.

If the user wants to minimize an app, then the best thing is to minimize it. If a user wants to exit an app, then by all means it is best to exit.

Is it frowned on? That's Android's view - they frown on it. And many many independent rookie Android developers frown on it.

But when it comes right down to it, there is good coding and bad coding. There is good program flow models and there are bad program flow models.

Leaving programs in memory when the user knows they are done with them simply is not good program flow. It serves absolutely no purpose whatsoever, and it slows things down when launching new apps or when running apps allocate more memory.

It is sort of like your car: There are times when you leave it running, like stopping at a stop light, or perhaps the fast food drive through, or stopping at the ATM. But there are other situations where you do want to shut it off - like when you get to work, or the grocery store or even home.

Similarly, if you're playing a game and the phone rings, yes. Pause the game and keep it running. But if the user is done with the game for a while, then by all means let them exit.

The exit button on some applications should be more out in front than others. Games, for example, or programs where the user is likely to want to fully exit, should have an obvious exit. Other programs, like, perhaps, email programs, where exiting is an unlikely desire (so that it can keep checking for email) -- these programs should not waste prime control input screen space with an exit option, but for good program flow, it should have an exit option. What if someone decides they don't want their mail program trying to check email when they are in poor coverage area, or maybe in a Skype call or whatever? Let them exit the email program if they want!

Suspending and exiting are two vital tasks and neither fulfills the role of the other.


Ich möchte hier nur eine Korrektur für die zukünftigen Leser dieses Threads hinzufügen. Diese besondere Nuance ist meinem Verständnis für eine lange Zeit entgangen, deshalb möchte ich sicherstellen, dass keiner von euch die gleichen Fehler macht:

System.exit() Ihre App nicht, wenn Sie mehr als eine Aktivität auf dem Stapel haben. Was tatsächlich passiert, ist, dass der Prozess beendet wird und sofort mit einer Aktivität auf dem Stapel neu gestartet wird . Dies ist auch der Fall, wenn Ihre App durch das Dialogfeld Schließen erzwungen wird oder wenn Sie versuchen, den Prozess von DDMS zu beenden. Dies ist eine Tatsache, die meines Wissens völlig undokumentiert ist.

Die kurze Antwort ist, wenn Sie Ihre Anwendung finish() möchten, müssen Sie alle Aktivitäten in Ihrem Stapel verfolgen und finish() ALLE finish() , wenn der Benutzer finish() möchte (und nein, es gibt keine Möglichkeit, durchzulaufen der Aktivitätsstapel, also musst du all das selbst verwalten). Auch dies tötet nicht den Prozess oder irgendwelche dangling Referenzen, die Sie haben können. Es beendet einfach die Aktivitäten. Ich bin mir auch nicht sicher, ob Process.killProcess(Process.myPid()) besser funktioniert; Ich habe es nicht getestet.

Wenn es andererseits für Sie in Ordnung ist, dass Aktivitäten in Ihrem Stack verbleiben, gibt es eine andere Methode, die Ihnen die Sache sehr leicht macht: Activity.moveTaskToBack(true) wird Ihren Prozess einfach im Hintergrund anzeigen und den Startbildschirm anzeigen.

Die lange Antwort beinhaltet die Erklärung der Philosophie hinter diesem Verhalten. Die Philosophie basiert auf einer Reihe von Annahmen:

  1. Dies geschieht zunächst nur, wenn Ihre App im Vordergrund ist. Wenn es im Hintergrund ist, wird der Prozess gut beendet. Wenn es jedoch im Vordergrund ist, nimmt das Betriebssystem an, dass der Benutzer weiter machen möchte, was auch immer er gerade macht. (Wenn Sie versuchen, den Prozess von DDMS zu beenden, sollten Sie zuerst die Home-Taste drücken und dann die Option beenden)
  2. Es setzt auch voraus, dass jede Aktivität unabhängig von allen anderen Aktivitäten ist. Dies ist häufig der Fall, wenn Ihre App beispielsweise die Browser-Aktivität startet, die völlig separat ist und nicht von Ihnen geschrieben wurde. Abhängig von den Manifestattributen kann die Browseraktivität für dieselbe Aufgabe erstellt werden oder auch nicht.
  3. Es geht davon aus, dass jede Ihrer Aktivitäten vollständig selbständig ist und in kürzester Zeit getötet / wiederhergestellt werden kann. (Ich mag diese bestimmte Annahme eher nicht, da meine App viele Aktivitäten hat, die auf einer großen Menge zwischengespeicherter Daten beruhen, die zu groß sind, um während onSaveInstanceState effizient serialisiert zu onSaveInstanceState , aber was wird das tun?) Für die meisten gut geschriebenen Android-Apps sollte das stimmen , da Sie nie wissen, wann Ihre App im Hintergrund gelöscht wird.
  4. Der letzte Faktor ist nicht so sehr eine Annahme, sondern eher eine Einschränkung des Betriebssystems: Das explizite Erlöschen der App ist mit dem Absturz der App identisch und das gleiche wie Android, das die App zum Wiederherstellen des Speichers beendet. Dies gipfelt in unserem Gnadenstoß: Da Android nicht feststellen kann, ob die App beendet wurde oder abgestürzt ist oder im Hintergrund getötet wurde, geht sie davon aus, dass der Benutzer dorthin zurückkehren möchte, wo er aufgehört hat, und der ActivityManager startet den Prozess neu.

Wenn Sie darüber nachdenken, ist dies für die Plattform geeignet. Erstens passiert genau das, wenn der Prozess im Hintergrund beendet wird und der Benutzer zu ihm zurückkehrt, so dass er dort neu gestartet werden muss, wo er aufgehört hat. Zweitens passiert das, wenn die App abstürzt und den gefürchteten Force Close-Dialog anzeigt.

Angenommen, ich möchte, dass meine Nutzer ein Bild aufnehmen und hochladen können. Ich starte die Kameraaktivität aus meiner Aktivität und fordere sie auf, ein Bild zurückzugeben. Die Kamera wird an die Spitze meiner aktuellen Aufgabe geschoben (anstatt in einer eigenen Aufgabe erstellt zu werden). Wenn die Kamera einen Fehler hat und abstürzt, sollte dies zum Absturz der gesamten App führen? Aus Sicht des Benutzers ist nur die Kamera ausgefallen und sie sollten zu ihrer vorherigen Aktivität zurückkehren. Es startet also den Prozess mit den gleichen Aktivitäten im Stapel, abzüglich der Kamera. Da Ihre Aktivitäten so gestaltet sein sollten , dass sie sofort getötet und wiederhergestellt werden können, sollte dies kein Problem darstellen. Leider können nicht alle Apps so gestaltet werden, so dass es für viele von uns ein Problem ist, ganz gleich, was Romain Guy oder jemand anderes Ihnen erzählt. Also müssen wir Workarounds verwenden.

Also, mein abschließender Ratschlag:

  • Versuche nicht, den Prozess zu beenden. Rufen Sie entweder finish() für alle Aktivitäten auf oder rufen Sie moveTaskToBack(true) .
  • Wenn Ihr Prozess abstürzt oder getötet wird, und wenn Sie wie ich die Daten benötigen, die sich im Speicher befanden und nun verloren sind, müssen Sie zur Stammaktivität zurückkehren. Um dies zu tun, sollten Sie startActivity() mit einem Intent Intent.FLAG_ACTIVITY_CLEAR_TOP , das das Flag Intent.FLAG_ACTIVITY_CLEAR_TOP enthält.
  • Wenn Sie Ihre App aus der DDMS-Perspektive von Eclipse beenden möchten, ist sie besser nicht im Vordergrund oder wird neu gestartet. Sie sollten zuerst die Home-Taste drücken und dann den Prozess beenden.

Diese Debatte läuft auf die uralte Frage hinaus, ob die Entwickler am besten wissen oder ob der Benutzer am besten Bescheid weiß. Professionelle Designer in allen Bereichen menschlicher Faktoren kämpfen damit jeden Tag.

Ted hat darauf hingewiesen, dass eine der am häufigsten heruntergeladenen Apps auf dem Markt der "App Killer" ist. Die Leute bekommen ein bisschen extra Serotonin, wenn sie Anwendungen beenden. Sie sind daran gewöhnt mit einem Desktop / Laptop. Es hält Dinge in Bewegung. Es hält den Prozessor kühl und der Lüfter schaltet sich ein. Es verbraucht weniger Energie.

Wenn Sie bedenken, dass ein mobiles Gerät ein viel kleineres Schiff ist, dann können Sie besonders ihren Anreiz schätzen, "über Bord zu werfen, was Sie nicht mehr brauchen". Jetzt haben die Entwickler von Android argumentiert, dass das Betriebssystem am besten weiß und dass das Beenden einer App antik ist. Ich unterstütze das von ganzem Herzen.

Ich glaube jedoch auch, dass Sie den Benutzer nicht frustrieren sollten, auch wenn diese Frustration aus ihrer eigenen Ignoranz resultiert. Aus diesem Grund komme ich zu dem Schluss, dass die Option "Beenden" ein gutes Design ist, auch wenn es sich meistens um einen Placebo-Button handelt, der lediglich eine Ansicht schließt.


Hören Sie auf, Ihre Anwendung als eine monolithische Anwendung zu betrachten. Es ist eine Reihe von UI-Bildschirmen, die der Benutzer mit Ihrer "Anwendung" und "Funktionen" über Android-Dienste interagieren kann.

Nicht zu wissen, was deine mysteriöse App "tut" ist nicht wirklich wichtig. Nehmen wir an, dass es sich in ein super sicheres Unternehmens-Intranet eintunnelt, eine Überwachung oder Interaktion durchführt und solange angemeldet bleibt, bis der Benutzer die Anwendung "beendet". Da Ihre IT-Abteilung es anweist, müssen sich Benutzer sehr bewusst sein, wann sie sich im Intranet befinden oder nicht. Daher ist es Ihre Einstellung, dass es für Benutzer wichtig ist, "aufzuhören".

Das ist einfach. Stellen Sie einen Dienst bereit, der eine fortlaufende Benachrichtigung in der Benachrichtigungsleiste mit der Meldung "Ich bin im Intranet, oder ich lebe" sendet. Lassen Sie diesen Dienst alle Funktionen ausführen, die Sie für Ihre Anwendung benötigen. Verfügen Sie über Aktivitäten, die an diesen Dienst gebunden sind, damit Ihre Benutzer auf die UI-Elemente zugreifen können, die sie für die Interaktion mit Ihrer "Anwendung" benötigen. Und haben Sie ein Android-Menü -> Beenden (oder Abmelden, oder was auch immer) -Taste, die den Dienst zum Beenden sagt, dann schließt die Aktivität selbst.

Dies ist für alle Absichten und Zwecke genau das, was Sie sagen, dass Sie wollen. Fertig für Android. Sehen Sie sich Google Talk oder Google Maps Navigation für Beispiele dieser "Exit" ist möglich Mentalität. Der einzige Unterschied besteht darin, dass das Zurückdrücken Ihrer Aktivität Ihren UNIX-Prozess in Gefahr bringt, falls der Benutzer Ihre Anwendung wiederbeleben möchte. Dies ist wirklich nicht anders als ein modernes Betriebssystem, das kürzlich zugegriffene Dateien im Speicher zwischenspeichert. Nachdem Sie Ihr Windows-Programm beendet haben, befinden sich die wahrscheinlichsten Ressourcen, die es benötigt, immer noch im Speicher und warten darauf, von anderen Ressourcen ersetzt zu werden, da sie jetzt geladen werden, wenn sie nicht mehr benötigt werden. Android ist das Gleiche.

Ich sehe dein Problem wirklich nicht.


The Linux kernel has a feature called Out-of-memory killer (as mentioned above, the policies are configurable at the userspace level as well as the kernel is not an optimal one, but by no means unnecessary).

And it is heavily used by Android:

Some userspace apps are available to assist with these kill apps, for example:


Sie können entweder durch Drücken der Zurück- Taste oder durch Aufrufen von finish() in Ihrer Activity finish() . Rufen Sie finish() MenuItem ein MenuItem wenn Sie es explizit ausschalten möchten.

Romain sagt nicht, dass es nicht machbar ist, nur dass es sinnlos ist - Benutzer müssen sich nicht darum kümmern, ihre Arbeit zu kündigen oder zu speichern, denn die Art und Weise, wie der Anwendungslebenszyklus funktioniert, ermutigt Sie, intelligente Software zu schreiben, die automatisch speichert und speichert stellt seinen Zustand wieder her, egal was passiert.


Almost 99% of the time there is no need for an Android application to take over its own life cycle. Most of the time it comes down to better planning or smarter design of the application. For example, rather build an internal service (not exported) to handle downloads, etc., or design actions and tasks around user workflow.

But that being said, where there is a will there is a way. Android provides - through the android.os.Process class, a much better API than Java to control the underlying process. And unlike Java it does not treat the developer like a moron by hiding it all behind a simple java.lang.System.exit() call.

So how do you ask your application to commit suicide in Android? Well, the trick is simple:

Create your own Android application class by inheriting from the standard android.app.Application class (remember to declare it in the AndroidManifest.xml file).

Override the onCreate() method, and store the process ID which started your application:

this.pid = android.os.Process.myPid(); // Save for later use.

Now to kill your application, provide a kill() method:

android.os.Process.sendSignal(pid, android.os.Process.SIGNAL_KILL);

Now whenever you need your app to commit suicide just type cast the application context, and call your kill method!

((MySuicidalApp) context.getApplicationContext()).kill()

Just remember that due to the process management policies in Android, specifically related to services, Android may just opt to restart your service (see You should not use task killers on Android ).


For closing an app at any point use FLAG_ACTIVITY_CLEAR_TOP flag in Intent and then system.exit();

Or there is similar way, but without system.exit() when you want to exit call this method:

public void exit() {
    startActivity(new Intent(this, HomeActivity.class).
    setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK).putExtra(EXIT_FLAG, true));
}

In your HomeActivity.onCreate() add following code

protected void onCreate(Bundle savedInstanceState) {
    if (getIntent().getBooleanExtra(EXIT_FLAG, false)) {
        if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
            finish();
        }
    }
......................

This will work without breaking the Android life-cycle.


I hope things will change over time. The user should be able to kill an app or process if the app process is sandboxed correctly by the OS. There is a notion that apps should be written perfectly or user will use only the apps that follow all SDK recommendations. I think that is a tall order.


Hmmmm...

I think that you just don't see the Android app the right way. You can do something almost like what you want easily:

  • Do the app activities save/restore state like it is encouraged in the developer livecycle documentation.

  • If some login is needed at the restore stage (no login/session information available) then do it.

  • Eventually add a button/menu/timeout in which case you will do a finish() without saving the login and other session info, making implicitly the end of app session: so if the app is started/brought to front again it will start a new session.

That way you don't really care if the app is really removed from memory or not.

If you really want to remove it from memory (this is discouraged, and BTW for what purpose?) you can kill it conditionally at the end of onDestroy() with java.lang.System.exit(0) (or perhaps restartPackage(..) ?). Of course do it only in the case where you want to "really end the app", because the onDestroy() is part of the normal lifecycle of activities and not an app end at all.


Dies ist eine interessante und aufschlussreiche Diskussion mit so vielen Experten. Ich denke, dass dieser Beitrag von der Android-Hauptwebsite zurückgeschleift werden sollte, da er sich um eines der Kerndesigns des Android-Betriebssystems dreht.

Ich möchte auch meine zwei Cent hier hinzufügen.

Bisher war ich beeindruckt von der Art und Weise, wie Android Lifecycle-Ereignisse behandelt, und bringt das Konzept eines webähnlichen Erlebnisses in native Apps.

Trotzdem glaube ich, dass es einen Quit Button geben sollte. Warum? ... nicht für mich oder Ted oder irgendeinen der Technologie-Gurus hier, sondern ausschließlich für die Erfüllung einer Endnutzer-Nachfrage.

Obwohl ich kein großer Fan von Windows bin, aber lange zurück, haben sie ein Konzept eingeführt, an das die meisten Endbenutzer gewöhnt sind (eine X-Taste) ... "Ich möchte ein Widget beenden, wenn ich es möchte".

Das heißt nicht, dass jemand (OS, Entwickler?) Das nach seinem eigenen Ermessen erledigen wird ... es bedeutet einfach "Wo ist mein Red X Button, an den ich gewöhnt bin". Meine Aktion sollte analog zu "Beenden eines Anrufs beim Drücken einer Taste", "Ausschalten des Geräts durch Drücken einer Taste" und so weiter und so fort sein ... es ist eine Wahrnehmung. Es bringt per se eine Befriedigung, dass mein Handeln tatsächlich seinen Zweck erfüllt.

Obwohl ein Entwickler dieses Verhalten unter Verwendung der hier gegebenen Vorschläge spoofieren kann, bleibt die Wahrnehmung bestehen, dass eine Anwendung (jetzt) ​​von einer unabhängigen, vertrauenswürdigen und neutralen Quelle (OS) auf Anforderung des Endbenutzers vollständig zu funktionieren aufhören sollte.


If you have 10,20 .. multiple Activities running and you want to finish all them and exit from system.

Create a static array in application class or constants class.

Constants

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity Fügt in diesem Array die aktuelle Aktivitätsreferenz hinzu

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView imageButton;
    private Activity activity;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activity = MainActivity.this;
        Constants.activities.add(activity);

        imageButton = (ImageView) findViewById(R.id.camera);
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}

Without an exit function for the application developer to kill their own application it is very bad design.

My application needs to allow the user to dynamically change data dynamically during runtime and the user needs to restart my application to make the change effect, but Android did not allow my application restart by itself. Android OS has a very bad design application life cycle.


Every time while you move to the next page through intent, use:

`YourActivityname.this.finish()`;

Beispiel:

Intent intent = new Intent(getApplicationContext(), SMS.class);

startActivity(intent);
MainActivity.this.finish();

So that no activity will be running on background and when you want to Exit your app, use:

MainActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
getParent().finish();

This exiting worked like a charm for me :)


There is a (relatively) simple design which will allow you to get around the "exit" conundrum. Make your app have a "base" state (activity) which is just a blank screen. On the first onCreate of the activity, you can launch another activity that your app's main functionality is in. The "exit" can then be accomplished by finish()ing this second activity and going back to the base of just a blank screen. The OS can keep this blank screen in memory for as long as it wants...

In essence, because you cannot exit out to OS, you simply transform into a self-created nothingness.


If you are unable to fathom how to make your data/connections (and thereby your "application") persistent, then you will be unable to do what you "need" to do with Android.

Those who do download those cutesy little App Killers usually find they do not help battery life or memory usage, but hinder the OS from doing it's job of managing memory efficiently...

http://android-developers.blogspot.com/2010/04/multitasking-android-way.html


I agree with Ted. I understand that exiting the application is not the "Android way", but it doesn't seem like it should be precluded. Here are three reasons why you might want a real exit to the application (not just the activity):

  1. The user might want some control over which app gets killed in the case of low memory. If important app A is running in the background, then you might like to exit app B when you are done with it so that app A doesn't get killed by the operating system.

  2. If your application has sensitive data cached in memory, you might like to kill the app so that a virus/worm/rogue app can't get at it. I know the security model is supposed to prevent that, but just in case...

  3. If your application uses resources (like network, CPU, sensors, etc.) that could adversely affect the phone, then one way of ensuring that those resources are freed up is to exit the application. I understand that well-behaved apps should free up resources when they are not needed. But again, exiting the application seems like a reasonable way of ensuring that.


First of all, never never never use System.exit(0). It is like making a person sleep punching him on the head!

Second: I'm facing this problem. Before sharing my solution a I want to share my thoughts.

I think that an "Exit Button" is stupid. Really really really stupid. And I think that users (consumer) that ask for an exit button for your application is stupid too. They don't understand how the OS is working and how is managing resources (and it does a great job).

I think that if you write a good piece of code that do the right things (updates, saves, and pushes) at the right moment and conditions and using the correct things (Service and Receiver) it will work pretty well and no one will complain.

But to do that you have to study and learn how things works on Android. Anyway, this is my solution to provide to users an "Exit Button".

I created an Options Menu always visible in each activity (I've a super activity that do that).

When the user clicks on that button this is what happens:

Intent intent = new Intent(this, DashBoardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

SharedPreferences settings = getSharedPreferences(getString(PREF_ID), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(FORCE_EXIT_APPLICATION, true);

  // Commit the edits!
editor.commit();
startActivity(intent);
finish();

So I'm saving in SharedPreferences that I want to kill my app, and I start an Intent. Please look at those flags; those will clear all my backstack calling my DashBoard Activity that is my "home" activity.

So in my Dashboard Activity I run this method in the onResume:

private void checkIfForceKill() {

    // CHECK IF I NEED TO KILL THE APP

    // Restore preferences
    SharedPreferences settings = getSharedPreferences(
            getString(MXMSettingHolder.PREF_ID), Context.MODE_PRIVATE);
    boolean forceKill = settings.getBoolean(
            MusicSinglePaneActivity.FORCE_EXIT_APPLICATION, false);

    if (forceKill) {

        //CLEAR THE FORCE_EXIT SETTINGS
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(FORCE_EXIT_APPLICATION, false);

        // Commit the edits!
        editor.commit();

        //HERE STOP ALL YOUR SERVICES
        finish();
    }
}

And it will work pretty well.

The only thing that I don't understand why it's happening is that when I do the last finish (and I've checked: it's following all the correct flow of onPause → onStop → onDestroy) the application is still on the recent activity (but it's blank).

It seems like the latest intent (that has started the DashboardActivity) is still in the system.

I've to dig more in order to also remove it.


Alle meine Anwendungen haben Schaltflächen zum Beenden ... und ich bekomme deswegen häufig positive Kommentare von Benutzern. Es ist mir egal, ob die Plattform so entworfen wurde, dass Anwendungen sie nicht benötigen. Zu sagen "bring sie nicht hin" ist irgendwie lächerlich. Wenn der Benutzer beenden möchte, biete ich ihnen den Zugang, genau das zu tun. Ich glaube nicht, dass es die Funktionsweise von Android reduziert und wie eine gute Praxis aussieht. Ich verstehe den Lebenszyklus ... und meine Beobachtung war, dass Android keine gute Arbeit damit macht ... und das ist eine grundlegende Tatsache.


Dies wird schließlich zu Ihrer Frage kommen, aber ich möchte zuerst eine Reihe von Fragen ansprechen, die Sie in Ihren verschiedenen Kommentaren zu den verschiedenen Antworten, die zum Zeitpunkt des Schreibens bereits gegeben wurden, aufwerfen. Ich habe nicht die Absicht, Ihre Meinung zu ändern - vielmehr sind diese hier für andere, die kommen, um diesen Beitrag in der Zukunft zu lesen.

Der Punkt ist, dass ich nicht zulassen kann, dass Android feststellt, wann meine App beendet wird. das muss die Wahl des Benutzers sein.

Millionen von Menschen sind vollkommen zufrieden mit dem Modell, bei dem die Umgebung die Anwendung nach Bedarf schließt. Diese Benutzer denken einfach nicht daran, die Android-App zu "beenden", genauso wenig wie sie über das "Beenden" einer Webseite oder das "Beenden" eines Thermostats nachdenken.

iPhone-Nutzer sind in etwa so, als dass das Drücken der iPhone-Taste nicht unbedingt so "gefühlt" wie die App abgebrochen wurde, da viele iPhone-Apps dort aufgehört haben, wo der Nutzer aufgehört hat (auch seit iPhone) ermöglicht zurzeit jeweils eine Drittanbieter-App).

Wie ich oben sagte, gibt es eine Menge Dinge in meiner App (Daten werden mit dem Gerät gepushed, Listen mit Aufgaben, die immer da sein sollten, etc.).

Ich weiß nicht, was "Listen mit Aufgaben, die immer da sein sollten" bedeutet, aber die "Daten, die an das Gerät PUSHed sind" ist eine angenehme Fiktion und sollte in keinem Fall durch eine Aktivität erledigt werden. Verwenden Sie eine geplante Aufgabe (via AlarmManager ), um Ihre Daten für maximale Zuverlässigkeit zu aktualisieren.

Unsere Nutzer melden sich an und können dies nicht jedes Mal tun, wenn sie einen Anruf erhalten und Android entscheidet, die App zu beenden.

Es gibt viele iPhone- und Android-Anwendungen, die damit umgehen. In der Regel liegt dies daran, dass sie Anmeldeinformationen speichern, anstatt Benutzer zu zwingen, sich jedes Mal manuell anzumelden.

Zum Beispiel möchten wir Updates beim Beenden der Anwendung überprüfen

Das ist ein Fehler auf jedem Betriebssystem. Der Grund dafür, dass Ihre Anwendung "beendet" ist, besteht darin, dass das Betriebssystem heruntergefahren wird und der Aktualisierungsprozess dann im Midstream fehlschlägt. Im Allgemeinen ist das keine gute Sache. Überprüfen Sie entweder die Updates beim Start oder überprüfen Sie die Updates vollständig asynchron (z. B. über eine geplante Aufgabe), niemals beim Beenden.

Einige Kommentare deuten darauf hin, dass das Drücken der Zurück-Taste die App überhaupt nicht zerstört (siehe Link in meiner Frage oben).

Durch Drücken der BACK-Taste wird die App nicht beendet. Es beendet die Aktivität, die auf dem Bildschirm angezeigt wurde, wenn der Benutzer die Schaltfläche ZURÜCK gedrückt hat.

Es sollte nur beendet werden, wenn die Benutzer es beenden möchten - niemals auf irgendeine andere Weise. Wenn du keine Apps schreiben kannst, die sich in Android so verhalten, dann denke ich, dass Android nicht zum Schreiben von echten Apps verwendet werden kann = (

Dann können auch keine Web-Anwendungen. Oder WebOS , wenn ich ihr Modell richtig verstehe (hatte noch keine Chance mit einem zu spielen). In all diesen Fällen "kündigen" die Benutzer nichts - sie verlassen einfach. Das iPhone ist ein bisschen anders, da es momentan nur eine Sache zu einer Zeit laufen lässt (mit ein paar Ausnahmen), und so bedeutet das Verlassen der App eine ziemlich sofortige Beendigung der App.

Gibt es eine Möglichkeit für mich, die Bewerbung wirklich zu beenden?

Wie alle anderen Ihnen gesagt haben, können Benutzer (über BACK) oder Ihr Code (über finish() ) Ihre aktuell laufenden Aktivitäten schließen. Benutzer benötigen im Allgemeinen für ordnungsgemäß geschriebene Anwendungen nichts anderes, als sie eine "Beenden" -Option für die Verwendung von Webanwendungen benötigen.

Keine zwei Anwendungsumgebungen sind per Definition identisch. Dies bedeutet, dass Sie Trends in Umgebungen sehen können, wenn neue entstehen und andere begraben werden.

Zum Beispiel gibt es eine wachsende Bewegung, um zu versuchen, den Begriff der "Datei" zu beseitigen. Die meisten Webanwendungen zwingen Benutzer nicht dazu, an Dateien zu denken. iPhone-Apps zwingen Benutzer normalerweise nicht dazu, an Dateien zu denken. Android-Apps zwingen Benutzer im Allgemeinen nicht dazu, an Dateien zu denken. Und so weiter.

In ähnlicher Weise gibt es eine wachsende Bewegung, um den Begriff "Beenden" einer App zu eliminieren. Die meisten Webanwendungen zwingen den Benutzer nicht dazu, sich abzumelden, sondern protokollieren den Benutzer implizit nach einem Zeitraum der Inaktivität. Das Gleiche gilt für Android und in geringerem Maße für das iPhone (und möglicherweise WebOS).

Dies erfordert eine stärkere Betonung des Anwendungsdesigns, die Fokussierung auf Geschäftsziele und nicht die Einhaltung eines Implementierungsmodells, das an eine frühere Anwendungsumgebung gebunden ist. Entwickler, denen die Zeit oder die Neigung fehlt, dies zu tun, werden frustriert mit neueren Umgebungen, die ihr bestehendes mentales Modell durchbrechen. Das ist nicht die Schuld der einen oder anderen Umgebung, ebenso wenig wie die Schuld eines Berges für Stürme, die ihn umströmen und nicht durch ihn.

Zum Beispiel hatten einige Entwicklungsumgebungen wie Hypercard und Smalltalk die Anwendung und die Entwicklungstools in einem Setup zusammengeführt. Dieses Konzept hat sich außerhalb von Spracherweiterungen für Apps (z. B. VBA in Excel , Lisp in AutoCAD ) nicht durchgesetzt . Entwickler, die mentale Modelle entwickelten, die die Existenz von Entwicklungswerkzeugen in der App selbst vermuteten, mussten daher entweder ihr Modell ändern oder sich auf Umgebungen beschränken, in denen ihr Modell gelten würde.

Also, wenn du schreibst:

Zusammen mit anderen unordentlichen Dingen, die ich entdeckt habe, denke ich, dass die Entwicklung unserer App für Android nicht passieren wird.

Das scheint für Sie das Beste zu sein, für jetzt. Ebenso würde ich Sie davon abraten, Ihre Anwendung ins Web zu portieren, da einige der Probleme, die Sie bei Android gemeldet haben, auch in Web-Anwendungen auftreten (z. B. keine "Kündigung"). Oder umgekehrt, wenn Sie Ihre App eines Tages ins Web portieren, stellen Sie möglicherweise fest, dass der Fluss der Webanwendung besser zu Android passt und Sie zu diesem Zeitpunkt einen Android-Port erneut aufrufen können.


It took me longer to read this Q&A than to actually implement a semi-proper Android Application Lifecycle.

It's a GPS app that polls for points and sends the current location to a webservice every few seconds using a thread... This could be polling every 5 minutes in Ted's case for an update, then onStop can simply start the update activity Ted was soo concerned about if one was found (asynchronous Ted, don't code like a Windows programmer or your programs will run like Windows programs ... eww, it's not that hard).

I did some initial code in onCreate to set up things for the activity lifetime, including checkUpdate.start(); :

...

@Override
public void onStart() {
    super.onStart();
    isRemote = true;
    checkUpdate.resume();

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, luh);
}

@Override
public void onPause() {
    isRemote = false;
    checkUpdate.suspend();
    locationManager.removeUpdates(luh);
    super.onStop();
}

This code may be completely wrong, but it works. This is one of my first Android applications.

Voilà, an application that doesn't consume CPU when it's in the background, yet is instantly ready to reopen because it is in RAM (although not holding RAM as is the Android lifecycle) ... an app is always ready, it's a phone, guys/gals. If an app was to use up all the RAM and couldn't be shut down by the OS then the thing might stop ringing =P That's why the OS needs to be able to close your app when it's in the background (if your application isn't a resource hog it won't be closed BTW), so let's just write better applications.


I would consider reading "Android Wireless Application Development" published by Addison-Wesley. I am just finishing it up and it is VERY thorough.

It appears that you have some fundamental misunderstandings of the Android platform. I too was a little frustrated at first with the application life-cycle of Android apps, but after coming to a greater understanding, I have come to really enjoy this approach. This book will answer all of your questions and much more. It really is the best resource I have found for new Android developers.

Also, I think you need to let go of a line-for-line port of the existing app. In order to port your application to the Android platform, some of the application design is going to change. The application-lifecycle used is necessary as mobile devices have very limited resources relative to desktop systems and allows Android devices to run several applications in an orderly and resource-aware fashion. Do some more in depth study of the platform, and I think you will realize that what you are wanting to do is entirely feasible. Best of luck.

By the way, I am no way affiliated with Addison-Wesley or any person or organization associated with this book. After re-reading my post I feel that I came off a little fanboyish. I just really, really enjoyed it and found it extremely helpful. :)


Die empfohlene Vorgehensweise ist die Verwendung von LocationClient :

Definieren Sie zunächst die Werte für den Standortaktualisierungsintervall. Passen Sie dies Ihren Bedürfnissen an.

private static final int MILLISECONDS_PER_SECOND = 1000;
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;

GooglePlayServicesClient.ConnectionCallbacks Sie Ihre Activity GooglePlayServicesClient.ConnectionCallbacks , GooglePlayServicesClient.OnConnectionFailedListener und LocationListener implementieren.

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {}

onCreate() dann einen LocationClient in der onCreate() -Methode Ihrer Activity :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mLocationClient = new LocationClient(this, this, this);

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
}

Fügen Sie Ihrer Activity die erforderlichen Methoden hinzu. onConnected() ist die Methode, die aufgerufen wird, wenn der LocationClient Verbindung herstellt. onLocationChanged() Sie den aktuellsten Speicherort ab.

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.w(TAG, "Location client connection failed");
}

@Override
public void onConnected(Bundle dataBundle) {
    Log.d(TAG, "Location client connected");
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
}

@Override
public void onDisconnected() {
    Log.d(TAG, "Location client disconnected");
}

@Override
public void onLocationChanged(Location location) {
    if (location != null) {
        Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude()));
    } else {
        Log.d(TAG, "Updated location NULL");
    } 
}     

Stellen Sie sicher, dass Sie den LocationClient anschließen / trennen, so dass nur eine zusätzliche Batterie verwendet wird, wenn dies absolut notwendig ist und das GPS nicht unbegrenzt läuft. Der LocationClient muss verbunden sein, um Daten von ihm zu erhalten.

public void onResume() {
    super.onResume();
    mLocationClient.connect();
}

public void onStop() {
    if (mLocationClient.isConnected()) {
        mLocationClient.removeLocationUpdates(this);
    }
    mLocationClient.disconnect();
    super.onStop();
}

Holen Sie sich den Standort des Benutzers. Versuchen Sie zunächst, den LocationClient . Wenn dies fehlschlägt, wechseln Sie zurück zum LocationManager .

public Location getLocation() {
    if (mLocationClient != null && mLocationClient.isConnected()) {
        return mLocationClient.getLastLocation();
    } else {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (locationManager != null) {
            Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (lastKnownLocationGPS != null) {
                return lastKnownLocationGPS;
            } else {
                return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            }
        } else {
            return null;
        }
    }
}




android