Реализация IntentService с использованием LinkedBlockingQueue?

#android

#Android

Вопрос:

Я пытаюсь загрузить несколько файлов с помощью IntentService. IntentService не загружает их нормально, как и ожидалось, по одному за раз, единственная проблема заключается в том, что при отключении Интернета служба намерений не остановит загрузку, скорее она застрянет в текущем потоке. Если мне удастся остановить текущий поток, он продолжит запускать другие потоки, хранящиеся в его очереди, даже если подключение к Интернету отключено.

В другом посте было предложено использовать LinkedBlockingQueue и создать свой собственный рабочий поток, который постоянно проверяет эту очередь на наличие новых потоков. Теперь я знаю, что при создании и уничтожении потоков возникают некоторые повышенные накладные расходы и, следовательно, проблемы с производительностью, но в моем случае это не проблема.

На данный момент все, что я хочу сделать, это понять, как работает IntentService, чего пока у меня нет (и я просмотрел код), а затем придумать для него свою собственную реализацию, используя LinkedBlockingQueue, управляемую рабочим потоком. Кто-нибудь делал это раньше? Может привести рабочий пример, если вам неудобно предоставлять исходный код, псевдокод меня устраивает. Спасибо!

ОБНОВЛЕНИЕ: в конечном итоге я реализовал свою собственную службу намерений, используя поток с циклом, который проверяет очередь, которая, в свою очередь, хранит намерения, переданные из startService (намерение).

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


}
  

Я не очень уверен в START_NOT_STICKY в методе onStartCommand(). Правильный ли это флаг для возврата или нет. Любые разъяснения по этому поводу были бы оценены!

Комментарии:

1. Я думаю, вместо того, чтобы загружать все эти файлы один за другим, я подумываю о том, чтобы сжать их, а затем загрузить zip-файл один раз, а затем, когда загрузка завершена, извлечь файлы на SD-карту, возможно ли это?

Ответ №1:

ОБНОВЛЕНИЕ: в конечном итоге я реализовал свою собственную службу намерений, используя поток с циклом, который проверяет очередь, которая, в свою очередь, хранит намерения, переданные из startService (намерение).

общедоступный класс MyIntentService расширяет сервис {

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