2013-04-18 4 views
12

Ich habe einen Intent-Dienst, der mehrere Gigabyte an Videos herunterlädt. Ich habe eine "Stop" -Taste, um den Download zu stoppen, wenn ich versehentlich "Start" oder was auch immer drücke. Ich weiß, das wurde ein paar Mal gefragt, aber ohne funktionierende Antwort für mich.So erzwingen Sie den Stopp Intent Service läuft?

Ich versuche stopService() aufzurufen, funktioniert nicht. Das ruft nur . Ich habe versucht, stopSelf() innerhalb onDestroy aufzurufen, funktioniert auch nicht.

Ich habe versucht, so etwas wie eine Flagge zu haben, aber onHandleIntent wird nicht aufgerufen, wenn es bereits läuft, es wartet bis die aktuelle Arbeit beendet ist und dann ausgeführt wird. Und selbst wenn das geklappt hätte, müsste ich sowas wie einen gigantischen if Statement haben, der saugt

Ist meine einzige Option wirklich das umschreiben auf einen regulären Service?

//

public class SyncService extends IntentService { 

    boolean isCanceled; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     if (intent.hasExtra("action")) { 

      // Set the canceling flag 
      isCanceled= intent.getStringExtra("action").equals("cancel"); 

     } 
     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     // Clean up the possible queue 
     if (intent.hasExtra ("action")) { 
      boolean cancel = intent.getStringExtra ("action"). Equals ("cancel"); 
      if (cancel) { 
       return; 
      } 
     } 

     ... 

     Get your inputStream from HttpUrlConnection or whatever 

     ... 

     while ((bytesRead = in.read(buffer)) > 0) { 
      if (isCanceled) { 
       isCanceled = false; 
       break; 
      } 

      ... 
     } 

    } 
} 

Antwort und lösen sie mit

Intent intent = new Intent(context, SyncService.class); 
intent.putExtra("action", "cancel"); 
context.startService(intent); 
+3

Sie könnten in Erwägung ziehen, Ihre Lösung aus Ihrer Frage zu entfernen und stattdessen als Lösung zur Verfügung zu stellen. – jbaums

Antwort

12

Sie haben zwei getrennte Fragen, würde ich denken:

  1. Wie den aktuellen Download zu stoppen

  2. Wie Downloads Warteschlange bis zu stoppen, die nach der aktuellen ausführen soll vervollständigt

Die erste zu sein „so etwas wie eine Fahne“ haben wird, dass Sie überprüfen, wie Sie die Daten herunterladen. Ansonsten wird nichts Ihren Download-Vorgang stoppen. Wenn Sie ein typisches HttpUrlConnection Rezept verwenden, überprüfen Sie das Flag in Ihrer Schleife, wo Sie aus dem HTTP InputStream lesen und schreiben Sie an Ihre . Sie setzen dieses Flag über einen Aufruf an startService() mit einer bestimmten Intent-Struktur und identifizieren es als "Abbrechen" -Operation. Sie müssten onStartCommand() in Ihrem IntentService überschreiben, schauen Sie sich die Intent an, verwenden Sie sie, um das Flag zu setzen, wenn es das Abbrechen Intent ist, oder Kette an die Oberklasse für jede andere Art von Intent.

Wenn Sie auch haben möglicherweise andere Befehle in der Warteschlange (Szenario # 2), müssten Sie diese Flagge an der Spitze der onHandleIntent() auch überprüfen.

+0

Ja genau wie du sagst. Wenn ich es in einen Service umschreibe, wäre ich in der Lage, es gewaltsam abzuschalten, oder wäre es dasselbe wie hier? – urSus

+0

@VlastoBennyLava: Es wäre mehr oder weniger dasselbe wie hier.Sie hätten besser die Möglichkeit, 'stopService()' und 'onDestroy()' zu verwenden, um das Flag zu setzen, aber Sie müssten Ihren eigenen Hintergrund-Thread und Ihre eigene Arbeitswarteschlange verwalten. – CommonsWare

+0

Ich habe meine Frage mit Antwort Pseudo-Code bearbeitet, möchten Sie es vielleicht überprüfen. Danke – urSus

2

Vorausgesetzt, dass Sie nicht wie Sie den Video-Download genau behandeln, funktioniert dies möglicherweise nicht (es wäre eine Art von Schleife innerhalb onHandleIntent, wo die Downloads ausgeführt werden). Sie können eine statische Klassenvariable innerhalb der IntentService verwenden, die den Stop/Start-Status des Downloads enthält, so dass sie von einem Activity festgelegt werden kann. Dann müssten Sie innerhalb von onHandleIntent den Status routinemäßig überprüfen, damit er weiß, wann die Vorgänge abgebrochen werden müssen.

Verwandte Themen