2011-11-04 12 views
7

Próbuję pobrać wiele plików za pomocą IntentService. IntentService donwloads nich okey zgodnie z oczekiwaniami, jedyny problem polega na tym, że gdy Internet jest wyłączony, usługa intent nie zatrzyma donwload, a raczej utknie w bieżącym wątku. Jeśli uda mi się zatrzymać bieżący wątek, nadal będą działać inne wątki przechowywane w jego kolejce, mimo że połączenie internetowe nie działa.Wdrożenie IntentService przy użyciu LinkedBlockingQueue?

Zasugerowano w innym poście, że używam LinkedBlockingQueue i tworzę własny wątek roboczy, który stale sprawdza kolejkę pod kątem nowych wątków. Teraz wiem, że są pewne zwiększone koszty ogólne, a co za tym idzie problemy z wydajnością podczas tworzenia i niszczenia wątków, ale nie jest to problemem w moim przypadku.

W tym miejscu chcę tylko zrozumieć, jak działa usługa IntentService, której jeszcze nie mam (i zajrzałem do kodu), a następnie wymyślić własną implementację za pomocą metody LinkedBlockingQueue kontrolowanej przez Wątek roboczy. Czy ktoś to wcześniej zrobił? Może dać dobry przykład, jeśli czujesz się niekomfortowo dostarczając kod źródłowy, pseudo kod jest w porządku. Dzięki!

UPDATE: ostatecznie wdrożone własne Intent obsługa za pomocą gwintu, który ma looper który sprawdza kolejkę, która z kolei zapisuje zamiary przekazywany z StartService (intent).

public class MyIntentService extends Service { 



    private BlockingQueue<Download> queue = new LinkedBlockingQueue<Download>(); 


    public MyIntentService(){ 
     super(); 
    } 



    @Override 
    public void onCreate() { 

     super.onCreate(); 

     new Thread(queueController).start(); 

     Log.e("onCreate","onCreate is running again"); 


    } 



    boolean killed = false; 
    Runnable queueController = new Runnable() { 
     public void run() { 
      while (true) { 
      try { 
       Download d =queue.take(); 

       if (killed) { 
       break; 
       } 
       else { 
       d.downloadFile(); 
       Log.e("QueueInfo","queue size: " + queue.size()); 
       } 
      } 
      catch (InterruptedException e) { 
       break; 
      } 

      } 
      Log.e("queueController", "queueController has finished processing"); 
      Log.e("QueueInfo","queue size: " + queue.toString()); 
     } 
     }; 

     class Download { 
      String name; 
      //Download files process 
      void downloadFile() { 
        //Download code here 
      } 

       Log.e("Download","Download being processed is: " + name); 
      } 
      public void setName(String n){ 
       name = n; 
      } 
      public String getName(){ 
       return name; 
      } 
     } 




    public void killService(){ 
     killed = true; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
      Download d = new Download(); 
     d.setName(intent.getStringExtra("VIDEOS")); 
     queue.add(d); 
     return START_NOT_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.e("stopSelf","stopSelf has been just called to stop the Service"); 
     stopSelf();  
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 


} 

Nie jestem tak pewny co do START_NOT_STICKY w metodzie onStartCommand(). Jeśli to właściwa flaga do zwrotu, czy nie. Wszelkie wyjaśnienia na ten temat zostaną docenione!

+0

myślę, zamiast pobierać wszystkie te pliki jeden po drugim, myślę o ich skompresowanie i następnie pobrać plik zip raz, a potem, gdy pobierania zakończone wyodrębnić pliki na karcie SD, czy to możliwe? – bytebiscuit

Odpowiedz

0

AKTUALIZACJA: W końcu zaimplementowałem własną usługę Intent Service za pomocą wątku z looperem, który sprawdza kolejkę, która z kolei przechowuje intencje przekazane z usługi startService (intent).

public class MyIntentService rozszerza usługę {

private BlockingQueue<Download> queue = new LinkedBlockingQueue<Download>(); 


public MyIntentService(){ 
    super(); 
} 



@Override 
public void onCreate() { 

    super.onCreate(); 

    new Thread(queueController).start(); 

    Log.e("onCreate","onCreate is running again"); 


} 



boolean killed = false; 
Runnable queueController = new Runnable() { 
    public void run() { 
     while (true) { 
     try { 
      Download d =queue.take(); 

      if (killed) { 
      break; 
      } 
      else { 
      d.downloadFile(); 
      Log.e("QueueInfo","queue size: " + queue.size()); 
      } 
     } 
     catch (InterruptedException e) { 
      break; 
     } 

     } 
     Log.e("queueController", "queueController has finished processing"); 
     Log.e("QueueInfo","queue size: " + queue.toString()); 
    } 
    }; 

    class Download { 
     String name; 
     //Download files process 
     void downloadFile() { 
       //Download code here 
     } 

      Log.e("Download","Download being processed is: " + name); 
     } 
     public void setName(String n){ 
      name = n; 
     } 
Powiązane problemy