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