2014-04-01 15 views
6

Ich bin gerade auf Android-Dienste, aber ich habe viele Zweifel. Hier sind einige Fragen. Bevor ich beginne, habe ich diese Seiten Android Services (official) Bounded Services (official) plus Sone Inner Klassen Theorie in meiner Sprache gelesen. Bitte sei geduldig, ich bin immer noch ein bisschen verwirrt.Bitte erklären Sie einige Android-Service-Konzepte

1) Zunächst unterscheidet sich ein Dienst von einer AsyncTask hauptsächlich dadurch, dass er auch weiterhin ausgeführt wird, wenn die App pausiert ist (d. H. Der Benutzer beobachtet eine andere App); In diesen Fällen wird AsyncTask beendet. Ist es in Ordnung oder irre ich mich? 2) Ein Dienst wird im selben Thread der Aktivität ausgeführt, die ihn über startService() gestartet hat. Um die Leistung der Aktivität nicht zu beeinträchtigen, muss ich einen separaten Thread für diesen Dienst erstellen, z. B. die Runnable-Schnittstelle implementieren. Eine andere Methode besteht darin, einen Dienst zu erstellen, der IntentService erweitert, der automatisch einen neuen Thread für den Dienst bereitstellt: Bei jedem Aufruf von onHandleIntent() wird ein neuer Thread erstellt.

Schauen wir uns jetzt mein konkretes Problem an. Ich muss einen Dienst erstellen, der von vielen Aktivitäten verwendet wird: Seine Aufgabe wird sein, alle 60 Sekunden eine Verbindung zur Server-DB herzustellen und nach Neuigkeiten zu suchen. Wenn eine Nachricht gefunden wird, benachrichtigen Sie, dass es eine neue Nachricht gibt (wenn wir auf MainActivity sind) oder zeigen Sie den neuen Nachrichtentitel an (wenn wir im Nachrichtenreader sind). Wie soll ich es kodieren? Ich habe eine MainActivity erstellt, die einen NewsService instanziiert und sofort startService() aufruft. Auf der anderen Seite habe ich den NewsService erweitert IntentService, dass (erstellt einen neuen Thread, wenn onHandleIntent aufgerufen wird?) Und sucht nach neuen Nachrichten. Ist es eine schlechte Idee, einen IntentService zu verwenden? Ich erkannte, dass es sehr hässlich sein wird, den Dienst zu starten, der startService() auf unbestimmte Zeit aufruft. Zu Beginn dieser Übung dachte ich, dass es eine gute Lösung ist, da es automatisch einen neuen Thread erstellt und die Implementierung des Dienstes vereinfacht. Aber jetzt habe ich einige Zweifel (ich kann nicht wissen, ob es eine Nachricht gibt! Wie kann MainActivity es wissen? Und wie man den Titel bekommt)

Dies sollte mit einer normalen erweitert Thread Klasse durchgeführt werden, die einen unendlichen cicle macht in seiner run() -Methode, nach Nachrichten alle 60 Sekunden überprüft und, wenn es eine neue gibt, liest den Titel von Remote-DB und Update-Aktivitäten Schaltflächen/Ansichten. Wenn die App dann vom Benutzer geschlossen wird, wird der Dienst ebenfalls geschlossen. Aber das Problem ist, dass, wenn ich solche Klasse Klasse ist es Arbeit gestoppt wird, wenn die MainActivity pausiert oder gestoppt ist, und andere Aktivitäten (der NewsReader in diesem Fall) kann keine Aktualisierung erhalten, weil der neue Thread keine Nachrichten im Moment erhält . Also brauche ich einen Service.

Ich hoffe, es ist klar. Wie sollte ich eine Lösung richtig umsetzen? Bitte markieren Sie alles falsch in meinem Text, ich muss wirklich lernen: D

Antwort

1

Sie scheinen alles richtig verstanden zu haben.

  • Verwenden AlarmManager zu planen Ihre Dienste:

    In Bezug auf Ihr spezielles Problem, würde ich folgende empfehlen. Lassen Sie die Service nicht laufen, wenn es nicht muss.

  • Verwenden Sie eine Broadcast Intent für neue Nachrichten. Alle Activities müssen eine innere BroadcastReceiver haben, die auf die Broadcast Absicht des Dienstes hört und dementsprechend reagiert.

+0

Danke. Ich weiß eigentlich nichts über Broadcast Intent und Broadcast Receiver: Wenn mir niemand eine Lösung gibt, gehe ich direkt auf die entsprechenden Docs: D. BTW, ich kann nicht glauben, dass ich alles verstanden habe xD – mark

+1

Dies kann Ihnen etwas Verständnis von "Broadcast" geben: http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html –

+0

Auch dieser Artikel hat Informationen über die Planung einer Service über 'AlarmManager' und über Updates per' Broadcasts': http://www.vogella.com/tutorials/AndroidServices/article.html –

0

Dienstleistungen ein guter Ansatz für, was Sie wollen, sie sind ziemlich gut Prozesse zu tun, wie hält einen Daemon im Hintergrund wenig Ressourcen verbrauchen, sind sie auch gute Meldungen ohne eine Aktivität zu zeigen, und am Laufen zu halten, auch wenn Sie beenden die Aktivität.

Wenn Sie mehr schwere Operationen in Ihrem Dienst ausführen müssen, können Sie immer noch AsyncTask verwenden, es starten, Ihre Operation in einem anderen Thread ausführen und automatisch das Ergebnis in Ihrem Hauptthread erhalten.

Wenn Sie den Dienst immer behalten wollen laufen Sie START_STICKY in der Service-

@Override 
    public int onStartCommand(final Intent intent, final int flags, 
     final int startId) { 
    // Ensure the service will restart if it dies 
    return START_STICKY; 
    } 

verwenden können, und Sie können den Dienst starten zu tun:

final Intent service = new Intent(); 
service.setComponent(new ComponentName(YourService.PACKAGE_NAME, 
    YourService.SERVICE_FULL_NAME)); 

// Start the service 
context.startService(service); 
0

1) Zunächst einmal, Ein Dienst unterscheidet sich von einer AsyncTask hauptsächlich dadurch, dass er auch weiterhin ausgeführt wird, wenn die App pausiert ist (dh der Benutzer beobachtet gerade eine andere App); In diesen Fällen wird AsyncTask beendet. Ist es ok oder bin ich falsch?

Dies ist nicht korrekt. AsyncTask ist ein Mechanismus zum Entladen der Hintergrundverarbeitung in einen separaten Thread und stellt einen Mechanismus bereit, um den Benutzer über Fortschritt, Fehler und Abschluss dieser Hintergrundverarbeitung zu informieren. AsyncTask funktioniert nicht, wenn die App angehalten wurde. Es führt weiterhin seine Verarbeitung im Hintergrund durch. Im Allgemeinen gibt es eine enge Verbindung zwischen einem AsyncTask und dem Activity, der es gestartet hat.

Eine Service, auf der anderen Seite, ist (allgemein) vollständig von der Activity entkoppelt, die es gestartet hat. A Service hat einen eigenen Lebenszyklus, der unabhängig von den anderen Aktivitäten in der App ist. Außerdem haben Dienste keine Benutzeroberfläche, daher sind sie nicht mit den visuellen Elementen der Anwendung verknüpft und sie bieten keine (direkten) Mechanismen für visuelles Feedback in Bezug auf Fortschritt, Fehler oder Abschluss. Dies muss separat programmiert werden.

2) Ein Dienst wird im selben Thread der Aktivität ausgeführt, die ihn über startService() gestartet hat. Um die Leistung der Aktivität nicht zu beeinflussen, muss ich einen separaten Thread für diesen Service erstellen, der zum Beispiel die Runnable-Schnittstelle implementiert. Eine andere Methode macht einen Dienst, der IntentService erweitert, der automatisch einen neuen Thread für den Dienst bereitstellt: ein neuer Thread ist erstellt für einen Aufruf onHandleIntent().

Dies ist auch nicht korrekt. Ein Service läuft nicht auf einem bestimmten Thread. Die Lifecycle-Methoden eines Service (onCreate(), onStartCommand() usw.) werden auf dem Hauptthread (UI) ausgeführt, der derselbe Thread sein kann oder nicht, der startService() aufgerufen wurde. Ein Service kann jedoch (und normalerweise) andere Hintergrundthreads starten, um die erforderliche Arbeit auszuführen.

IntentService ist eine bestimmte Art von Service, die einen oder mehrere Worker-Threads verwaltet, die für die Hintergrundverarbeitung verwendet werden.Sie senden einen "Befehl" an eine IntentService und die IntentService setzt dann Ihren Befehl in eine Warteschlange. Irgendwann (unterschiedliche Implementierungen in verschiedenen Android-Versionen verhalten sich anders) wird Ihr "Befehl" aus der Warteschlange entfernt und in einem Hintergrundthread verarbeitet. IntentService stoppt sich selbst, nachdem alle "Befehle" verarbeitet wurden. IntentService ist oft nicht die beste Wahl für eine Service aufgrund der Art, wie es sich verhält.


IntentService ist definitiv nicht das, was Sie in Ihrem Fall wollen. Sie sollten wahrscheinlich AlarmManager verwenden und einen Alarm einstellen, der Ihre Service jede Minute startet. Wenn Ihr Service startet, sollte es einen Hintergrund-Thread erstellen, der Ihren Server kontaktiert und nach Neuigkeiten sucht. Wenn es keine Neuigkeiten gibt, kann es einfach verschwinden. Wenn es neue Nachrichten gibt, kann es entweder Ihren Activity starten, um den Benutzer zu informieren, oder es kann eine Sendung Intent senden, die Ihr Activity sehen wird (wenn es ausgeführt wird), oder es könnte ein Notification erstellen, das der Benutzer wann immer dann öffnen kann möchte. Sie müssen herausfinden, wie Sie festlegen möchten, wann die App den Server nicht mehr überprüfen soll. Vielleicht sollte der Benutzer Ihnen sagen, dass er nicht mehr interessiert ist, oder vielleicht kann die Service erkennen, dass die App nicht mehr läuft (oder nicht in mehr als X Stunden oder was auch immer geschaut wurde). Es gibt viele Möglichkeiten, dies zu tun, und es hängt von Ihren Anforderungen ab.

Verwandte Themen