diff --git a/app/src/main/java/org/tasks/caldav/CaldavSynchronizer.java b/app/src/main/java/org/tasks/caldav/CaldavSynchronizer.java index b1d40fba1..1c508249d 100644 --- a/app/src/main/java/org/tasks/caldav/CaldavSynchronizer.java +++ b/app/src/main/java/org/tasks/caldav/CaldavSynchronizer.java @@ -92,15 +92,7 @@ public class CaldavSynchronizer { this.client = client; } - public void sync() { - // required for dav4android (ServiceLoader) - Thread.currentThread().setContextClassLoader(context.getClassLoader()); - for (CaldavAccount account : caldavDao.getAccounts()) { - sync(account); - } - } - - private void sync(CaldavAccount account) { + public void sync(CaldavAccount account) { if (!inventory.hasPro()) { setError(account, context.getString(R.string.requires_pro_subscription)); return; diff --git a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java index 292dd2cca..2d8cde856 100644 --- a/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java +++ b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java @@ -131,29 +131,25 @@ public class GoogleTaskSynchronizer { } } - public void sync() { - List accounts = googleTaskListDao.getAccounts(); - for (int i = 0; i < accounts.size(); i++) { - GoogleTaskAccount account = accounts.get(i); - Timber.d("%s: start sync", account); - try { - if (i == 0 || inventory.hasPro()) { - synchronize(account); - account.setError(""); - } else { - account.setError(context.getString(R.string.requires_pro_subscription)); - } - } catch (UserRecoverableAuthIOException e) { - Timber.e(e); - sendNotification(context, e.getIntent()); - } catch (Exception e) { - account.setError(e.getMessage()); - tracker.reportException(e); - } finally { - googleTaskListDao.update(account); - localBroadcastManager.broadcastRefreshList(); - Timber.d("%s: end sync", account); + public void sync(GoogleTaskAccount account, int i) { + Timber.d("%s: start sync", account); + try { + if (i == 0 || inventory.hasPro()) { + synchronize(account); + account.setError(""); + } else { + account.setError(context.getString(R.string.requires_pro_subscription)); } + } catch (UserRecoverableAuthIOException e) { + Timber.e(e); + sendNotification(context, e.getIntent()); + } catch (Exception e) { + account.setError(e.getMessage()); + tracker.reportException(e); + } finally { + googleTaskListDao.update(account); + localBroadcastManager.broadcastRefreshList(); + Timber.d("%s: end sync", account); } } @@ -220,7 +216,8 @@ public class GoogleTaskSynchronizer { } if (preferences.isPositionHackEnabled()) { for (TaskList list : gtaskLists) { - List tasks = fetchPositions(gtasksInvoker, list.getId()); + List tasks = + fetchPositions(gtasksInvoker, list.getId()); for (com.google.api.services.tasks.model.Task task : tasks) { googleTaskDao.updatePosition(task.getId(), task.getParent(), task.getPosition()); } @@ -230,8 +227,8 @@ public class GoogleTaskSynchronizer { account.setEtag(eTag); } - private List fetchPositions(GtasksInvoker gtasksInvoker, String listId) - throws IOException { + private List fetchPositions( + GtasksInvoker gtasksInvoker, String listId) throws IOException { List tasks = new ArrayList<>(); String nextPageToken = null; do { diff --git a/app/src/main/java/org/tasks/jobs/SyncWork.java b/app/src/main/java/org/tasks/jobs/SyncWork.java index 9772b60b8..60963208e 100644 --- a/app/src/main/java/org/tasks/jobs/SyncWork.java +++ b/app/src/main/java/org/tasks/jobs/SyncWork.java @@ -1,12 +1,22 @@ package org.tasks.jobs; +import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybeanMR1; +import static java.util.concurrent.Executors.newFixedThreadPool; + import android.content.Context; import androidx.annotation.NonNull; import androidx.work.WorkerParameters; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import org.tasks.LocalBroadcastManager; import org.tasks.analytics.Tracker; import org.tasks.caldav.CaldavSynchronizer; +import org.tasks.data.CaldavAccount; +import org.tasks.data.CaldavDao; +import org.tasks.data.GoogleTaskAccount; +import org.tasks.data.GoogleTaskListDao; import org.tasks.gtasks.GoogleTaskSynchronizer; import org.tasks.injection.InjectingWorker; import org.tasks.injection.JobComponent; @@ -21,6 +31,8 @@ public class SyncWork extends InjectingWorker { @Inject LocalBroadcastManager localBroadcastManager; @Inject Preferences preferences; @Inject Tracker tracker; + @Inject CaldavDao caldavDao; + @Inject GoogleTaskListDao googleTaskListDao; public SyncWork(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); @@ -38,8 +50,20 @@ public class SyncWork extends InjectingWorker { preferences.setSyncOngoing(true); localBroadcastManager.broadcastRefresh(); try { - caldavSynchronizer.sync(); - googleTaskSynchronizer.sync(); + int numThreads = atLeastJellybeanMR1() ? Runtime.getRuntime().availableProcessors() : 2; + ExecutorService executor = newFixedThreadPool(numThreads); + + for (CaldavAccount account : caldavDao.getAccounts()) { + executor.execute(() -> caldavSynchronizer.sync(account)); + } + List accounts = googleTaskListDao.getAccounts(); + for (int i = 0; i < accounts.size(); i++) { + int count = i; + executor.execute(() -> googleTaskSynchronizer.sync(accounts.get(count), count)); + } + + executor.shutdown(); + executor.awaitTermination(15, TimeUnit.MINUTES); } catch (Exception e) { tracker.reportException(e); } finally {