2013-04-18 8 views
12

Ho un servizio intent che scarica diversi gigabyte di video. Ho un pulsante "Stop", per interrompere il download se colpisci accidentalmente "Start" o qualsiasi altra cosa. So che questo è stato chiesto un paio di volte ma senza una risposta funzionante per me.Come forzare l'arresto di Intent Service in corso?

Provo a chiamare stopService(), non funziona. Questo chiama solo IntentService.OnDestroy(). Ho provato a chiamare stopSelf() all'interno di onDestroy, non funziona neanche.

Ho provato ad avere qualcosa come una bandiera, ma onHandleIntent non viene chiamato se è già in esecuzione, attende fino a quando il lavoro corrente è terminato e viene eseguito. E anche se questo avrebbe funzionato, avrei dovuto avere qualcosa di simile a una dichiarazione gigante, che fa schifo

La mia unica opzione è davvero quella di riscriverlo a un servizio regolare?

// Risposta

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; 
      } 

      ... 
     } 

    } 
} 

e innescare con

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

Si potrebbe considerare di rimuovere la soluzione dalla domanda e invece di fornirla come soluzione. – jbaums

risposta

12

Hai due questioni separate, penserei:

  1. come fermare il download corrente

  2. Come smettere di coda i download, che dovrebbe eseguire dopo quella corrente completano

La prima sta andando ad avere per essere "qualcosa di simile a una bandiera", che si controlla come si scaricano i dati. In caso contrario, nulla interromperà l'operazione di download. Se si utilizza una tipica ricetta HttpUrlConnection, si controlla quella bandiera nel proprio loop in cui si legge da HTTP InputStream e si scrive sul numero FileOutputStream. Si imposta questo flag tramite una chiamata a startService() con una particolare struttura Intent, identificandola come un'operazione di "annullamento". Dovresti eseguire l'override di nel tuo IntentService, guardare lo Intent, usarlo per impostare il flag se è l'annullamento Intent o la catena sulla superclasse per qualsiasi altro tipo di Intent.

Se si anche potrebbero avere altri comandi in coda (scenario n. 2), sarà necessario controllare tale contrassegno nella parte superiore di onHandleIntent().

+0

Sì esattamente come dici tu. Se lo riscrivo su un servizio, sarei in grado di spegnerlo con forza o sarebbe la stessa cosa che qui? – urSus

+0

@VlastoBennyLava: Sarebbe la stessa cosa di qui, più o meno.Avresti una migliore capacità di usare forse 'stopService()' e 'onDestroy()' per impostare il flag, ma dovresti gestire il tuo thread in background e la coda di lavoro. – CommonsWare

+0

Ho modificato la mia domanda con lo pseudo codice di risposta, potresti voler controllare. Grazie – urSus

2

Dato che non è stato pubblicato come si sta gestendo il download del video esattamente, questo potrebbe non funzionare (ci sarebbe una sorta di ciclo all'interno di onHandleIntent dove vengono eseguiti i download). È possibile utilizzare una variabile di classe statica all'interno dello IntentService che contiene lo stato Stop/Start del download, in modo che possa essere impostato da Activity. Quindi, all'interno di onHandleIntent, è necessario verificare periodicamente lo stato in modo da sapere quando annullare le operazioni.