Posting downloaders on executor
This commit is contained in:
parent
fe17f1bcb5
commit
366e60990d
|
@ -28,6 +28,7 @@ import de.danoeh.antennapod.core.service.GpodnetSyncService;
|
||||||
import de.danoeh.antennapod.core.service.download.handler.FailedDownloadHandler;
|
import de.danoeh.antennapod.core.service.download.handler.FailedDownloadHandler;
|
||||||
import de.danoeh.antennapod.core.service.download.handler.FeedSyncTask;
|
import de.danoeh.antennapod.core.service.download.handler.FeedSyncTask;
|
||||||
import de.danoeh.antennapod.core.service.download.handler.MediaDownloadedHandler;
|
import de.danoeh.antennapod.core.service.download.handler.MediaDownloadedHandler;
|
||||||
|
import de.danoeh.antennapod.core.service.download.handler.PostDownloaderTask;
|
||||||
import de.danoeh.antennapod.core.storage.DBReader;
|
import de.danoeh.antennapod.core.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||||
|
@ -82,23 +83,21 @@ public class DownloadService extends Service {
|
||||||
*/
|
*/
|
||||||
public static final String EXTRA_REQUEST = "request";
|
public static final String EXTRA_REQUEST = "request";
|
||||||
|
|
||||||
|
public static final int NOTIFICATION_ID = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all completed downloads that have not been included in the report yet.
|
* Contains all completed downloads that have not been included in the report yet.
|
||||||
*/
|
*/
|
||||||
private List<DownloadStatus> reportQueue;
|
private final List<DownloadStatus> reportQueue;
|
||||||
|
private final ExecutorService syncExecutor;
|
||||||
private ExecutorService syncExecutor;
|
private final CompletionService<Downloader> downloadExecutor;
|
||||||
private CompletionService<Downloader> downloadExecutor;
|
private final DownloadRequester requester;
|
||||||
|
private final DownloadServiceNotification notificationManager;
|
||||||
private DownloadRequester requester;
|
|
||||||
|
|
||||||
private DownloadServiceNotification notificationManager;
|
|
||||||
public static final int NOTIFICATION_ID = 2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently running downloads.
|
* Currently running downloads.
|
||||||
*/
|
*/
|
||||||
private List<Downloader> downloads;
|
private final List<Downloader> downloads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of running downloads.
|
* Number of running downloads.
|
||||||
|
@ -114,11 +113,10 @@ public class DownloadService extends Service {
|
||||||
|
|
||||||
private NotificationUpdater notificationUpdater;
|
private NotificationUpdater notificationUpdater;
|
||||||
private ScheduledFuture<?> notificationUpdaterFuture;
|
private ScheduledFuture<?> notificationUpdaterFuture;
|
||||||
|
private ScheduledFuture<?> downloadPostFuture;
|
||||||
private static final int SCHED_EX_POOL_SIZE = 1;
|
private static final int SCHED_EX_POOL_SIZE = 1;
|
||||||
private ScheduledThreadPoolExecutor schedExecutor;
|
private ScheduledThreadPoolExecutor schedExecutor;
|
||||||
|
|
||||||
private final Handler postHandler = new Handler();
|
|
||||||
|
|
||||||
private final IBinder mBinder = new LocalBinder();
|
private final IBinder mBinder = new LocalBinder();
|
||||||
|
|
||||||
private class LocalBinder extends Binder {
|
private class LocalBinder extends Binder {
|
||||||
|
@ -243,29 +241,13 @@ public class DownloadService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public DownloadService() {
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
||||||
if (intent.getParcelableExtra(EXTRA_REQUEST) != null) {
|
|
||||||
onDownloadQueued(intent);
|
|
||||||
} else if (numberOfDownloads.get() == 0) {
|
|
||||||
stopSelf();
|
|
||||||
}
|
|
||||||
return Service.START_NOT_STICKY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
Log.d(TAG, "Service started");
|
|
||||||
isRunning = true;
|
|
||||||
handler = new Handler();
|
|
||||||
reportQueue = Collections.synchronizedList(new ArrayList<>());
|
reportQueue = Collections.synchronizedList(new ArrayList<>());
|
||||||
downloads = Collections.synchronizedList(new ArrayList<>());
|
downloads = Collections.synchronizedList(new ArrayList<>());
|
||||||
numberOfDownloads = new AtomicInteger(0);
|
numberOfDownloads = new AtomicInteger(0);
|
||||||
|
requester = DownloadRequester.getInstance();
|
||||||
|
notificationManager = new DownloadServiceNotification(this);
|
||||||
|
|
||||||
IntentFilter cancelDownloadReceiverFilter = new IntentFilter();
|
|
||||||
cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_ALL_DOWNLOADS);
|
|
||||||
cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_DOWNLOAD);
|
|
||||||
registerReceiver(cancelDownloadReceiver, cancelDownloadReceiverFilter);
|
|
||||||
syncExecutor = Executors.newSingleThreadExecutor(r -> {
|
syncExecutor = Executors.newSingleThreadExecutor(r -> {
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
t.setPriority(Thread.MIN_PRIORITY);
|
t.setPriority(Thread.MIN_PRIORITY);
|
||||||
|
@ -288,9 +270,31 @@ public class DownloadService extends Service {
|
||||||
return t;
|
return t;
|
||||||
}, (r, executor) -> Log.w(TAG, "SchedEx rejected submission of new task")
|
}, (r, executor) -> Log.w(TAG, "SchedEx rejected submission of new task")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
if (intent.getParcelableExtra(EXTRA_REQUEST) != null) {
|
||||||
|
onDownloadQueued(intent);
|
||||||
|
} else if (numberOfDownloads.get() == 0) {
|
||||||
|
stopSelf();
|
||||||
|
}
|
||||||
|
return Service.START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
Log.d(TAG, "Service started");
|
||||||
|
isRunning = true;
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
|
IntentFilter cancelDownloadReceiverFilter = new IntentFilter();
|
||||||
|
cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_ALL_DOWNLOADS);
|
||||||
|
cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_DOWNLOAD);
|
||||||
|
registerReceiver(cancelDownloadReceiver, cancelDownloadReceiverFilter);
|
||||||
|
|
||||||
downloadCompletionThread.start();
|
downloadCompletionThread.start();
|
||||||
requester = DownloadRequester.getInstance();
|
|
||||||
notificationManager = new DownloadServiceNotification(this);
|
|
||||||
Notification notification = notificationManager.updateNotifications(
|
Notification notification = notificationManager.updateNotifications(
|
||||||
requester.getNumberOfDownloads(), downloads);
|
requester.getNumberOfDownloads(), downloads);
|
||||||
startForeground(NOTIFICATION_ID, notification);
|
startForeground(NOTIFICATION_ID, notification);
|
||||||
|
@ -312,7 +316,6 @@ public class DownloadService extends Service {
|
||||||
reportQueue.clear();
|
reportQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
postHandler.removeCallbacks(postDownloaderTask);
|
|
||||||
EventBus.getDefault().postSticky(DownloadEvent.refresh(Collections.emptyList()));
|
EventBus.getDefault().postSticky(DownloadEvent.refresh(Collections.emptyList()));
|
||||||
|
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
@ -323,6 +326,7 @@ public class DownloadService extends Service {
|
||||||
syncExecutor.shutdown();
|
syncExecutor.shutdown();
|
||||||
schedExecutor.shutdown();
|
schedExecutor.shutdown();
|
||||||
cancelNotificationUpdater();
|
cancelNotificationUpdater();
|
||||||
|
downloadPostFuture.cancel(true);
|
||||||
unregisterReceiver(cancelDownloadReceiver);
|
unregisterReceiver(cancelDownloadReceiver);
|
||||||
|
|
||||||
// if this was the initial gpodder sync, i.e. we just synced the feeds successfully,
|
// if this was the initial gpodder sync, i.e. we just synced the feeds successfully,
|
||||||
|
@ -566,42 +570,20 @@ public class DownloadService extends Service {
|
||||||
|
|
||||||
private class NotificationUpdater implements Runnable {
|
private class NotificationUpdater implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
handler.post(() -> {
|
Notification n = notificationManager.updateNotifications(requester.getNumberOfDownloads(), downloads);
|
||||||
Notification n = notificationManager.updateNotifications(
|
if (n != null) {
|
||||||
requester.getNumberOfDownloads(), downloads);
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
if (n != null) {
|
nm.notify(NOTIFICATION_ID, n);
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
}
|
||||||
nm.notify(NOTIFICATION_ID, n);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private long lastPost = 0;
|
|
||||||
|
|
||||||
private final Runnable postDownloaderTask = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
List<Downloader> runningDownloads = new ArrayList<>();
|
|
||||||
for (Downloader downloader : downloads) {
|
|
||||||
if (!downloader.cancelled) {
|
|
||||||
runningDownloads.add(downloader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Downloader> list = Collections.unmodifiableList(runningDownloads);
|
|
||||||
EventBus.getDefault().postSticky(DownloadEvent.refresh(list));
|
|
||||||
postHandler.postDelayed(postDownloaderTask, 1500);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void postDownloaders() {
|
private void postDownloaders() {
|
||||||
long now = System.currentTimeMillis();
|
new PostDownloaderTask(downloads).run();
|
||||||
if (now - lastPost >= 250) {
|
|
||||||
postHandler.removeCallbacks(postDownloaderTask);
|
if (downloadPostFuture == null) {
|
||||||
postDownloaderTask.run();
|
downloadPostFuture = schedExecutor.scheduleAtFixedRate(
|
||||||
lastPost = now;
|
new PostDownloaderTask(downloads), 1, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public abstract class Downloader implements Callable<Downloader> {
|
||||||
|
|
||||||
private volatile boolean finished;
|
private volatile boolean finished;
|
||||||
|
|
||||||
volatile boolean cancelled;
|
public volatile boolean cancelled;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
final DownloadRequest request;
|
final DownloadRequest request;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package de.danoeh.antennapod.core.service.download.handler;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||||
|
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PostDownloaderTask implements Runnable {
|
||||||
|
private List<Downloader> downloads;
|
||||||
|
|
||||||
|
public PostDownloaderTask(List<Downloader> downloads) {
|
||||||
|
this.downloads = downloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
List<Downloader> runningDownloads = new ArrayList<>();
|
||||||
|
for (Downloader downloader : downloads) {
|
||||||
|
if (!downloader.cancelled) {
|
||||||
|
runningDownloads.add(downloader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Downloader> list = Collections.unmodifiableList(runningDownloads);
|
||||||
|
EventBus.getDefault().postSticky(DownloadEvent.refresh(list));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue