From 52421d81f73277557a2ba2ad097379f105213d98 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 6 Feb 2021 12:05:10 +0100 Subject: Removed some unnecessary calls to startForeground --- .../core/service/download/DownloadService.java | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'core/src/main/java/de') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index 025088273..bc696f444 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -192,10 +192,6 @@ public class DownloadService extends Service { registerReceiver(cancelDownloadReceiver, cancelDownloadReceiverFilter); downloadCompletionThread.start(); - - Notification notification = notificationManager.updateNotifications( - requester.getNumberOfDownloads(), downloads); - startForeground(R.id.notification_downloading, notification); } @Override @@ -551,20 +547,13 @@ public class DownloadService extends Service { private void queryDownloads() { Log.d(TAG, numberOfDownloads.get() + " downloads left"); + setupNotificationUpdaterIfNecessary(); + notificationUpdater.run(); + if (numberOfDownloads.get() <= 0 && DownloadRequester.getInstance().hasNoDownloads()) { - Log.d(TAG, "Number of downloads is " + numberOfDownloads.get() + ", attempting shutdown"); + Log.d(TAG, "Attempting shutdown"); stopForeground(true); stopSelf(); - if (notificationUpdater != null) { - notificationUpdater.run(); - } else { - Log.d(TAG, "Skipping notification update"); - } - } else { - setupNotificationUpdater(); - Notification notification = notificationManager.updateNotifications( - requester.getNumberOfDownloads(), downloads); - startForeground(R.id.notification_downloading, notification); } } @@ -617,7 +606,7 @@ public class DownloadService extends Service { /** * Schedules the notification updater task if it hasn't been scheduled yet. */ - private void setupNotificationUpdater() { + private void setupNotificationUpdaterIfNecessary() { if (notificationUpdater == null) { Log.d(TAG, "Setting up notification updater"); notificationUpdater = new NotificationUpdater(); -- cgit v1.2.3 From 4aa54435298b4d21d070069c2569adb894435604 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 6 Feb 2021 12:32:53 +0100 Subject: Refresh all feeds at once instead of sending tons of lists with 1 feed each --- .../de/danoeh/antennapod/core/storage/DBTasks.java | 100 ++++++++------------- .../antennapod/core/storage/DownloadRequester.java | 31 +++++-- 2 files changed, 61 insertions(+), 70 deletions(-) (limited to 'core/src/main/java/de') diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java index 48a3f574a..f5a8fb07a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java @@ -16,7 +16,6 @@ import de.danoeh.antennapod.core.event.MessageEvent; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.feed.FeedPreferences; import de.danoeh.antennapod.core.feed.LocalFeedUpdater; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadStatus; @@ -31,6 +30,7 @@ import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -121,7 +121,18 @@ public final class DBTasks { throw new IllegalStateException("DBTasks.refreshAllFeeds() must not be called from the main thread."); } - refreshFeeds(context, DBReader.getFeedList(), initiatedByUser); + List feeds = DBReader.getFeedList(); + ListIterator iterator = feeds.listIterator(); + while (iterator.hasNext()) { + if (!iterator.next().getPreferences().getKeepUpdated()) { + iterator.remove(); + } + } + try { + refreshFeeds(context, feeds, false, false, false); + } catch (DownloadRequestException e) { + e.printStackTrace(); + } isRefreshing.set(false); SharedPreferences prefs = context.getSharedPreferences(PREF_NAME, MODE_PRIVATE); @@ -134,38 +145,6 @@ public final class DBTasks { // See Issue #2577 for the details of the rationale } - /** - * @param context - * @param feedList the list of feeds to refresh - * @param initiatedByUser a boolean indicating if the refresh was triggered by user action. - */ - private static void refreshFeeds(final Context context, - final List feedList, - boolean initiatedByUser) { - - for (Feed feed : feedList) { - FeedPreferences prefs = feed.getPreferences(); - // feeds with !getKeepUpdated can only be refreshed - // directly from the FeedActivity - if (prefs.getKeepUpdated()) { - try { - refreshFeed(context, feed); - } catch (DownloadRequestException e) { - e.printStackTrace(); - DBWriter.addDownloadStatus( - new DownloadStatus(feed, - feed.getHumanReadableIdentifier(), - DownloadError.ERROR_REQUEST_ERROR, - false, - e.getMessage(), - initiatedByUser) - ); - } - } - } - - } - /** * Downloads all pages of the given feed even if feed has not been modified since last refresh * @@ -174,7 +153,7 @@ public final class DBTasks { */ public static void forceRefreshCompleteFeed(final Context context, final Feed feed) { try { - refreshFeed(context, feed, true, true, false); + refreshFeeds(context, Collections.singletonList(feed), true, true, false); } catch (DownloadRequestException e) { e.printStackTrace(); DBWriter.addDownloadStatus( @@ -209,19 +188,6 @@ public final class DBTasks { } } - /** - * Refresh a specific Feed. The refresh may get canceled if the feed does not seem to be modified - * and the last update was only few days ago. - * - * @param context Used for requesting the download. - * @param feed The Feed object. - */ - private static void refreshFeed(Context context, Feed feed) - throws DownloadRequestException { - Log.d(TAG, "refreshFeed(feed.id: " + feed.getId() +")"); - refreshFeed(context, feed, false, false, false); - } - /** * Refresh a specific feed even if feed has not been modified since last refresh * @@ -230,26 +196,32 @@ public final class DBTasks { */ public static void forceRefreshFeed(Context context, Feed feed, boolean initiatedByUser) throws DownloadRequestException { - Log.d(TAG, "refreshFeed(feed.id: " + feed.getId() +")"); - refreshFeed(context, feed, false, true, initiatedByUser); + Log.d(TAG, "refreshFeed(feed.id: " + feed.getId() + ")"); + refreshFeeds(context, Collections.singletonList(feed), false, true, initiatedByUser); } - private static void refreshFeed(Context context, Feed feed, boolean loadAllPages, boolean force, boolean initiatedByUser) - throws DownloadRequestException { - Feed f; - String lastUpdate = feed.hasLastUpdateFailed() ? null : feed.getLastUpdate(); - if (feed.getPreferences() == null) { - f = new Feed(feed.getDownload_url(), lastUpdate, feed.getTitle()); - } else { - f = new Feed(feed.getDownload_url(), lastUpdate, feed.getTitle(), - feed.getPreferences().getUsername(), feed.getPreferences().getPassword()); + private static void refreshFeeds(Context context, List feeds, boolean loadAllPages, + boolean force, boolean initiatedByUser) throws DownloadRequestException { + List localFeeds = new ArrayList<>(); + List normalFeeds = new ArrayList<>(); + + for (Feed feed : feeds) { + if (feed.isLocalFeed()) { + localFeeds.add(feed); + } else { + normalFeeds.add(feed); + } } - f.setId(feed.getId()); - if (f.isLocalFeed()) { - new Thread(() -> LocalFeedUpdater.updateFeed(f, context)).start(); - } else { - DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages, force, initiatedByUser); + if (!localFeeds.isEmpty()) { + new Thread(() -> { + for (Feed feed : localFeeds) { + LocalFeedUpdater.updateFeed(feed, context); + } + }).start(); + } + if (!normalFeeds.isEmpty()) { + DownloadRequester.getInstance().downloadFeeds(context, feeds, loadAllPages, force, initiatedByUser); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index e3121caa2..638c1bef5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -17,6 +17,7 @@ import org.apache.commons.io.FilenameUtils; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -184,16 +185,31 @@ public class DownloadRequester implements DownloadStateProvider { } /** - * Downloads a feed + * Downloads a feed. * * @param context The application's environment. - * @param feed Feed to download + * @param feed Feeds to download * @param loadAllPages Set to true to download all pages */ public synchronized void downloadFeed(Context context, Feed feed, boolean loadAllPages, - boolean force, boolean initiatedByUser) - throws DownloadRequestException { - if (feedFileValid(feed)) { + boolean force, boolean initiatedByUser) throws DownloadRequestException { + downloadFeeds(context, Collections.singletonList(feed), loadAllPages, force, initiatedByUser); + } + + /** + * Downloads a list of feeds. + * + * @param context The application's environment. + * @param feeds Feeds to download + * @param loadAllPages Set to true to download all pages + */ + public synchronized void downloadFeeds(Context context, List feeds, boolean loadAllPages, + boolean force, boolean initiatedByUser) throws DownloadRequestException { + List requests = new ArrayList<>(); + for (Feed feed : feeds) { + if (!feedFileValid(feed)) { + continue; + } String username = (feed.getPreferences() != null) ? feed.getPreferences().getUsername() : null; String password = (feed.getPreferences() != null) ? feed.getPreferences().getPassword() : null; String lastModified = feed.isPaged() || force ? null : feed.getLastUpdate(); @@ -206,9 +222,12 @@ public class DownloadRequester implements DownloadStateProvider { true, username, password, lastModified, true, args, initiatedByUser ); if (request != null) { - download(context, request); + requests.add(request); } } + if (!requests.isEmpty()) { + download(context, requests.toArray(new DownloadRequest[0])); + } } public synchronized void downloadFeed(Context context, Feed feed) throws DownloadRequestException { -- cgit v1.2.3 From b1bf77d4e3c368641eb6801dd36affbe9846a154 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 6 Feb 2021 16:23:38 +0100 Subject: New workaround for hiding the notification directly --- .../core/service/download/DownloadService.java | 24 +++++++++++++--------- .../download/DownloadServiceNotification.java | 5 ++++- 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'core/src/main/java/de') diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index bc696f444..4a17fbbda 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -169,6 +169,7 @@ public class DownloadService extends Service { Notification notification = notificationManager.updateNotifications( requester.getNumberOfDownloads(), downloads); startForeground(R.id.notification_downloading, notification); + setupNotificationUpdaterIfNecessary(); syncExecutor.execute(() -> onDownloadQueued(intent)); } else if (numberOfDownloads.get() == 0) { stopForeground(true); @@ -254,13 +255,13 @@ public class DownloadService extends Service { handleSuccessfulDownload(downloader); removeDownload(downloader); numberOfDownloads.decrementAndGet(); - queryDownloadsAsync(); + stopServiceIfEverythingDoneAsync(); }); } else { handleFailedDownload(downloader); removeDownload(downloader); numberOfDownloads.decrementAndGet(); - queryDownloadsAsync(); + stopServiceIfEverythingDoneAsync(); } } catch (InterruptedException e) { Log.e(TAG, "DownloadCompletionThread was interrupted"); @@ -409,7 +410,7 @@ public class DownloadService extends Service { } postDownloaders(); } - queryDownloads(); + stopServiceIfEverythingDone(); } }; @@ -480,7 +481,7 @@ public class DownloadService extends Service { postDownloaders(); }); } - handler.post(this::queryDownloads); + handler.post(this::stopServiceIfEverythingDone); } private static boolean isEnqueued(@NonNull DownloadRequest request, @@ -537,23 +538,26 @@ public class DownloadService extends Service { * Calls query downloads on the services main thread. This method should be used instead of queryDownloads if it is * used from a thread other than the main thread. */ - private void queryDownloadsAsync() { - handler.post(DownloadService.this::queryDownloads); + private void stopServiceIfEverythingDoneAsync() { + handler.post(DownloadService.this::stopServiceIfEverythingDone); } /** * Check if there's something else to download, otherwise stop. */ - private void queryDownloads() { + private void stopServiceIfEverythingDone() { Log.d(TAG, numberOfDownloads.get() + " downloads left"); - setupNotificationUpdaterIfNecessary(); - notificationUpdater.run(); - if (numberOfDownloads.get() <= 0 && DownloadRequester.getInstance().hasNoDownloads()) { Log.d(TAG, "Attempting shutdown"); stopForeground(true); stopSelf(); + + // Trick to hide the notification more quickly when the service is stopped + // Without this, the second-last update of the notification stays for 3 seconds after onDestroy returns + notificationUpdater.run(); + NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + nm.cancel(R.id.notification_downloading); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java index 4fae9f34a..64ed85cf3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceNotification.java @@ -28,7 +28,10 @@ public class DownloadServiceNotification { private void setupNotificationBuilders() { notificationCompatBuilder = new NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID_DOWNLOADING) - .setOngoing(true) + .setOngoing(false) + .setWhen(0) + .setOnlyAlertOnce(true) + .setShowWhen(false) .setContentIntent(ClientConfig.downloadServiceCallbacks.getNotificationContentIntent(context)) .setSmallIcon(R.drawable.ic_notification_sync); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { -- cgit v1.2.3