diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-06-12 15:46:48 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2021-06-12 15:46:48 +0300 |
commit | 73a78b2a9e54972221bed65d39a8dd5b38f4e4a1 (patch) | |
tree | eab02ddcb43c674dd6278eca9a67be1bc1ad2261 | |
parent | ea7839c6cb042ca162286bec62706e0948ee3661 (diff) |
Use executors for more control over started threads
Signed-off-by: Stefan Niedermann <info@niedermann.it>
9 files changed, 102 insertions, 69 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/LiveDataHelper.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/LiveDataHelper.java index 10a18bb09..059ed5e6b 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/LiveDataHelper.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/LiveDataHelper.java @@ -6,38 +6,24 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; import androidx.lifecycle.Observer; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import static androidx.lifecycle.Transformations.distinctUntilChanged; public class LiveDataHelper { - public interface DataChangeProcessor<T> { - void onDataChanged(T data); + private LiveDataHelper() { + throw new UnsupportedOperationException("This class must not be instantiated."); } - public interface DataTransformator<I, O> { - O transform(I data); - } - - public interface LiveDataWrapper<T> { - T getData(); - - default void postResult(WrappedLiveData<T> liveData) { - liveData.setError(null); - T data = null; - try { - data = getData(); - } catch (RuntimeException e) { - liveData.setError(e); - } - liveData.postValue(data); - } - } + private static final ExecutorService executor = Executors.newCachedThreadPool(); public static <T> LiveData<T> interceptLiveData(LiveData<T> data, DataChangeProcessor<T> onDataChange) { MediatorLiveData<T> ret = new MediatorLiveData<>(); ret.addSource(data, changedData -> - doAsync(() -> { + executor.submit(() -> { onDataChange.onDataChanged(changedData); ret.postValue(changedData); }) @@ -47,32 +33,29 @@ public class LiveDataHelper { public static <I, O> LiveData<O> postCustomValue(LiveData<I> data, DataTransformator<I, O> transformator) { - MediatorLiveData<O> ret = new MediatorLiveData<>(); - - ret.addSource(data, changedData -> doAsync(() -> ret.postValue(transformator.transform(changedData)))); + final MediatorLiveData<O> ret = new MediatorLiveData<>(); + ret.addSource(data, changedData -> executor.submit(() -> ret.postValue(transformator.transform(changedData)))); return distinctUntilChanged(ret); } public static <I> MediatorLiveData<I> of(I oneShot) { - MediatorLiveData<I> ret = new MediatorLiveData<I>() { + return new MediatorLiveData<I>() { @Override public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { super.observe(owner, observer); - doAsync(() -> postValue(oneShot)); + executor.submit(() -> postValue(oneShot)); } }; - return ret; } public static <I, O> LiveData<O> postSingleValue(LiveData<I> data, DataTransformator<I, O> transformator) { - MediatorLiveData<O> ret = new MediatorLiveData<>(); - - ret.addSource(data, changedData -> doAsync(() -> ret.postValue(transformator.transform(changedData)))); + final MediatorLiveData<O> ret = new MediatorLiveData<>(); + ret.addSource(data, changedData -> executor.submit(() -> ret.postValue(transformator.transform(changedData)))); return distinctUntilChanged(ret); } public static <T> void observeOnce(LiveData<T> liveData, LifecycleOwner owner, Observer<T> observer) { - Observer<T> tempObserver = new Observer<T>() { + final Observer<T> tempObserver = new Observer<T>() { @Override public void onChanged(T result) { liveData.removeObserver(this); @@ -85,7 +68,7 @@ public class LiveDataHelper { public static <T> WrappedLiveData<T> wrapInLiveData(final LiveDataWrapper<T> liveDataWrapper) { final WrappedLiveData<T> liveData = new WrappedLiveData<>(); - doAsync(() -> { + executor.submit(() -> { try { liveDataWrapper.postResult(liveData); } catch (Throwable t) { @@ -96,7 +79,26 @@ public class LiveDataHelper { return liveData; } - private static void doAsync(Runnable r) { - new Thread(r).start(); + public interface DataChangeProcessor<T> { + void onDataChanged(T data); + } + + public interface DataTransformator<I, O> { + O transform(I data); + } + + public interface LiveDataWrapper<T> { + T getData(); + + default void postResult(WrappedLiveData<T> liveData) { + liveData.setError(null); + T data = null; + try { + data = getData(); + } catch (RuntimeException e) { + liveData.setError(e); + } + liveData.postValue(data); + } } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java index 3d05247b3..4a90664c9 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/util/extrawurst/UserSearchLiveData.java @@ -18,12 +18,12 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.DataBaseAdapter public class UserSearchLiveData extends MediatorLiveData<List<User>> implements Debouncer.Callback<Long> { private static final int DEBOUNCE_TIME = 300; // ms - private DataBaseAdapter db; - private ServerAdapter server; + private final DataBaseAdapter db; + private final ServerAdapter server; long accountId; String searchTerm; long notYetAssignedInACL; - private Debouncer<Long> debouncer = new Debouncer<>(this, DEBOUNCE_TIME); + private final Debouncer<Long> debouncer = new Debouncer<>(this, DEBOUNCE_TIME); public UserSearchLiveData(DataBaseAdapter db, ServerAdapter server) { this.db = db; diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java index f1f584df6..4648e34c3 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java @@ -19,6 +19,8 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import it.niedermann.android.crosstabdnd.DragAndDropAdapter; import it.niedermann.android.crosstabdnd.DraggedItemLocalState; @@ -45,6 +47,7 @@ import static it.niedermann.nextcloud.deck.util.MimeTypeUtil.TEXT_PLAIN; public class CardAdapter extends RecyclerView.Adapter<AbstractCardViewHolder> implements DragAndDropAdapter<FullCard>, CardOptionsItemSelectedListener, Branded { + private final ExecutorService executor; private final boolean compactMode; @NonNull protected final MainViewModel mainViewModel; @@ -66,6 +69,10 @@ public class CardAdapter extends RecyclerView.Adapter<AbstractCardViewHolder> im protected final int maxCoverImages; public CardAdapter(@NonNull Activity activity, @NonNull FragmentManager fragmentManager, long stackId, @NonNull MainViewModel mainViewModel, @Nullable SelectCardListener selectCardListener) { + this(activity, fragmentManager, stackId, mainViewModel, selectCardListener, Executors.newSingleThreadExecutor()); + } + + private CardAdapter(@NonNull Activity activity, @NonNull FragmentManager fragmentManager, long stackId, @NonNull MainViewModel mainViewModel, @Nullable SelectCardListener selectCardListener, @NonNull ExecutorService executor) { this.activity = activity; this.counterMaxValue = this.activity.getString(R.string.counter_max_value); this.fragmentManager = fragmentManager; @@ -79,6 +86,7 @@ public class CardAdapter extends RecyclerView.Adapter<AbstractCardViewHolder> im ? activity.getResources().getInteger(R.integer.max_cover_images) : 0; setHasStableIds(true); + this.executor = executor; } @Override @@ -204,10 +212,10 @@ public class CardAdapter extends RecyclerView.Adapter<AbstractCardViewHolder> im .putExtra(Intent.EXTRA_TEXT, CardUtil.getCardContentAsString(activity, fullCard)); activity.startActivity(Intent.createChooser(shareIntent, fullCard.getCard().getTitle())); } else if (itemId == R.id.action_card_assign) { - new Thread(() -> mainViewModel.assignUserToCard(mainViewModel.getUserByUidDirectly(fullCard.getCard().getAccountId(), account.getUserName()), fullCard.getCard())).start(); + executor.submit(() -> mainViewModel.assignUserToCard(mainViewModel.getUserByUidDirectly(fullCard.getCard().getAccountId(), account.getUserName()), fullCard.getCard())); return true; } else if (itemId == R.id.action_card_unassign) { - new Thread(() -> mainViewModel.unassignUserFromCard(mainViewModel.getUserByUidDirectly(fullCard.getCard().getAccountId(), account.getUserName()), fullCard.getCard())).start(); + executor.submit(() -> mainViewModel.unassignUserFromCard(mainViewModel.getUserByUidDirectly(fullCard.getCard().getAccountId(), account.getUserName()), fullCard.getCard())); return true; } else if (itemId == R.id.action_card_move) { DeckLog.verbose("[Move card] Launch move dialog for " + Card.class.getSimpleName() + " \"" + fullCard.getCard().getTitle() + "\" (#" + fullCard.getLocalId() + ") from " + Stack.class.getSimpleName() + " #" + +stackId); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java index 4b6d308ae..9dc7020b3 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/attachments/CardAttachmentsFragment.java @@ -38,6 +38,8 @@ import java.io.IOException; import java.time.Instant; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import id.zelory.compressor.constraint.FormatConstraint; import id.zelory.compressor.constraint.QualityConstraint; @@ -95,6 +97,7 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentDelet private PreviewDialogViewModel previewViewModel; private BottomSheetBehavior<LinearLayout> mBottomSheetBehaviour; private boolean compressImagesOnUpload = true; + private final ExecutorService executor = Executors.newCachedThreadPool(); private RecyclerView.ItemDecoration galleryItemDecoration; @@ -406,7 +409,7 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentDelet DeckLog.verbose("--- found content URL", sourceUri.getPath()); // Separate Thread required because picked file might not yet be locally available // https://github.com/stefan-niedermann/nextcloud-deck/issues/814 - new Thread(() -> { + executor.submit(() -> { try { final File originalFile = copyContentUriToTempFile(requireContext(), sourceUri, editViewModel.getAccount().getId(), editViewModel.getFullCard().getLocalId()); requireActivity().runOnUiThread(() -> { @@ -432,7 +435,7 @@ public class CardAttachmentsFragment extends Fragment implements AttachmentDelet } catch (IOException e) { requireActivity().runOnUiThread(() -> ExceptionDialogFragment.newInstance(e, editViewModel.getAccount()).show(getChildFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); } - }).start(); + }); break; } default: { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java index 23336c91f..8914a87ed 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/upcomingcards/UpcomingCardsViewModel.java @@ -7,6 +7,8 @@ import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.model.Account; @@ -19,10 +21,12 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiv public class UpcomingCardsViewModel extends AndroidViewModel { private final SyncManager syncManager; + private final ExecutorService executor; public UpcomingCardsViewModel(@NonNull Application application) { super(application); this.syncManager = new SyncManager(application); + this.executor = Executors.newCachedThreadPool(); } public LiveData<List<UpcomingCardsAdapterItem>> getUpcomingCards() { @@ -30,11 +34,11 @@ public class UpcomingCardsViewModel extends AndroidViewModel { } public void assignUser(@NonNull Account account, @NonNull Card card) { - new Thread(() -> syncManager.assignUserToCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)).start(); + executor.submit(() -> syncManager.assignUserToCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)); } public void unassignUser(@NonNull Account account, @NonNull Card card) { - new Thread(() -> syncManager.unassignUserFromCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)).start(); + executor.submit(() -> syncManager.unassignUserFromCard(syncManager.getUserByUidDirectly(card.getAccountId(), account.getUserName()), card)); } public void archiveCard(@NonNull FullCard card, @NonNull IResponseCallback<FullCard> callback) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/filter/FilterWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/filter/FilterWidget.java index 89d75eeee..56ea508c0 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/filter/FilterWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/filter/FilterWidget.java @@ -7,7 +7,11 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import androidx.annotation.NonNull; + import java.util.NoSuchElementException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.model.Account; @@ -18,26 +22,26 @@ import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE; public class FilterWidget extends AppWidgetProvider { public static final String ACCOUNT_KEY = "filter_widget_account"; public static final String BUNDLE_KEY = "filter_widget_bundle"; + final ExecutorService executor = Executors.newCachedThreadPool(); - static void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds, Account account) { + static void updateAppWidget(@NonNull ExecutorService executor, @NonNull Context context, AppWidgetManager awm, int[] appWidgetIds, Account account) { final SyncManager syncManager = new SyncManager(context); - for (int appWidgetId : appWidgetIds) { - new Thread(() -> { + executor.submit(() -> { try { // TODO implement throw new UnsupportedOperationException("Not yet implemented"); } catch (NoSuchElementException e) { // onUpdate has been triggered before the user finished configuring the widget } - }).start(); + }); } } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); - updateAppWidget(context, appWidgetManager, appWidgetIds, null); + updateAppWidget(executor, context, appWidgetManager, appWidgetIds, null); } @Override @@ -56,10 +60,10 @@ public class FilterWidget extends AppWidgetProvider { if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { if (intent.getExtras() != null) { - updateAppWidget(context, awm, new int[]{intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)}, account); + updateAppWidget(executor, context, awm, new int[]{intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)}, account); } } else { - updateAppWidget(context, awm, awm.getAppWidgetIds(new ComponentName(context, FilterWidget.class)), account); + updateAppWidget(executor, context, awm, awm.getAppWidgetIds(new ComponentName(context, FilterWidget.class)), account); } } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java index 766948062..b3e4d622b 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java @@ -15,6 +15,8 @@ import androidx.annotation.IdRes; import androidx.annotation.NonNull; import java.util.NoSuchElementException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.Card; @@ -25,11 +27,13 @@ import it.niedermann.nextcloud.deck.util.DateUtil; public class SingleCardWidget extends AppWidgetProvider { + private final ExecutorService executor = Executors.newCachedThreadPool(); + void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds) { final SyncManager syncManager = new SyncManager(context); for (int appWidgetId : appWidgetIds) { - new Thread(() -> { + executor.submit(() -> { try { final FullSingleCardWidgetModel fullModel = syncManager.getSingleCardWidgetModelDirectly(appWidgetId); @@ -106,7 +110,7 @@ public class SingleCardWidget extends AppWidgetProvider { } catch (NoSuchElementException e) { // onUpdate has been triggered before the user finished configuring the widget } - }).start(); + }); } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java index 5b0907ef3..02d426bbb 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java @@ -10,6 +10,10 @@ import android.net.Uri; import android.widget.RemoteViews; import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; @@ -23,11 +27,12 @@ import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE; public class StackWidget extends AppWidgetProvider { private static final int PENDING_INTENT_OPEN_APP_RQ = 0; private static final int PENDING_INTENT_EDIT_CARD_RQ = 1; + private final ExecutorService executor = Executors.newCachedThreadPool(); @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); - updateAppWidget(context, appWidgetManager, appWidgetIds); + updateAppWidget(executor, context, appWidgetManager, appWidgetIds); } @Override @@ -40,10 +45,10 @@ public class StackWidget extends AppWidgetProvider { if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); DeckLog.verbose(ACTION_APPWIDGET_UPDATE, "for", StackWidget.class.getSimpleName(), "with id", appWidgetId, "→ perform update."); - updateAppWidget(context, awm, new int[]{appWidgetId}); + updateAppWidget(executor, context, awm, new int[]{appWidgetId}); } else { DeckLog.verbose(ACTION_APPWIDGET_UPDATE, "→ Triggering update for all widgets of type", StackWidget.class.getSimpleName()); - updateAppWidget(context, awm, awm.getAppWidgetIds(new ComponentName(context, StackWidget.class))); + updateAppWidget(executor, context, awm, awm.getAppWidgetIds(new ComponentName(context, StackWidget.class))); } } } @@ -59,10 +64,10 @@ public class StackWidget extends AppWidgetProvider { } } - private static void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds) { + private static void updateAppWidget(@NonNull ExecutorService executor, @NonNull Context context, AppWidgetManager awm, int[] appWidgetIds) { final SyncManager syncManager = new SyncManager(context); for (int appWidgetId : appWidgetIds) { - new Thread(() -> { + executor.submit(() -> { if (syncManager.filterWidgetExists(appWidgetId)) { final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_stack); @@ -94,7 +99,7 @@ public class StackWidget extends AppWidgetProvider { } else { DeckLog.warn("Does not yet exist"); } - }).start(); + }); } } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java index a28f1ef4f..42c7989dd 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java @@ -12,6 +12,8 @@ import android.widget.RemoteViews; import androidx.annotation.NonNull; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.stream.Collectors; import it.niedermann.nextcloud.deck.BuildConfig; @@ -35,6 +37,7 @@ public class UpcomingWidget extends AppWidgetProvider { private static final String PENDING_INTENT_ACTION_OPEN = "open"; private static final String PENDING_INTENT_PARAM_LOCAL_CARD_ID = "localCardId"; private static final String PENDING_INTENT_PARAM_ACCOUNT_ID = "accountId"; + private final ExecutorService executor = Executors.newCachedThreadPool(); @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { @@ -42,10 +45,10 @@ public class UpcomingWidget extends AppWidgetProvider { final SyncManager syncManager = new SyncManager(context); for (int appWidgetId : appWidgetIds) { - new Thread(() -> { + executor.submit(() -> { if (syncManager.filterWidgetExists(appWidgetId)) { DeckLog.warn(UpcomingWidget.class.getSimpleName(), "with id", appWidgetId, "already exists, perform update instead."); - updateAppWidget(context, appWidgetManager, appWidgetIds); + updateAppWidget(executor, context, appWidgetManager, appWidgetIds); } else { final List<Account> accountsList = syncManager.readAccountsDirectly(); final FilterWidget config = new FilterWidget(appWidgetId, EWidgetType.UPCOMING_WIDGET); @@ -59,7 +62,7 @@ public class UpcomingWidget extends AppWidgetProvider { @Override public void onResponse(Integer response) { DeckLog.verbose("Successfully created", UpcomingWidget.class.getSimpleName(), "with id", appWidgetId); - updateAppWidget(context, appWidgetManager, appWidgetIds); + updateAppWidget(executor, context, appWidgetManager, appWidgetIds); } @Override @@ -70,7 +73,7 @@ public class UpcomingWidget extends AppWidgetProvider { } }); } - }).start(); + }); } } @@ -84,17 +87,17 @@ public class UpcomingWidget extends AppWidgetProvider { if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); DeckLog.verbose(ACTION_APPWIDGET_UPDATE, "for", UpcomingWidget.class.getSimpleName(), "with id", appWidgetId, "→ perform update."); - updateAppWidget(context, awm, new int[]{appWidgetId}); + updateAppWidget(executor, context, awm, new int[]{appWidgetId}); } else { DeckLog.verbose(ACTION_APPWIDGET_UPDATE, "→ Triggering update for all widgets of type", UpcomingWidget.class.getSimpleName()); - updateAppWidget(context, awm, awm.getAppWidgetIds(new ComponentName(context, UpcomingWidget.class))); + updateAppWidget(executor, context, awm, awm.getAppWidgetIds(new ComponentName(context, UpcomingWidget.class))); } } else if (PENDING_INTENT_ACTION_EDIT.equals(intent.getAction())) { if (intent.hasExtra(PENDING_INTENT_PARAM_ACCOUNT_ID) && intent.hasExtra(PENDING_INTENT_PARAM_LOCAL_CARD_ID)) { - new Thread(() -> { + executor.submit(() -> { final SyncManager syncManager = new SyncManager(context); context.startActivity(EditActivity.createEditCardIntent(context, syncManager.readAccountDirectly(intent.getLongExtra(PENDING_INTENT_PARAM_ACCOUNT_ID, -1)), syncManager.getBoardLocalIdByLocalCardIdDirectly(intent.getLongExtra(PENDING_INTENT_PARAM_LOCAL_CARD_ID, -1)), intent.getLongExtra(PENDING_INTENT_PARAM_LOCAL_CARD_ID, -1))); - }).start(); + }); } else { DeckLog.error(PENDING_INTENT_PARAM_ACCOUNT_ID, "and", PENDING_INTENT_PARAM_LOCAL_CARD_ID, "must be provided for action", PENDING_INTENT_ACTION_EDIT); } @@ -114,9 +117,9 @@ public class UpcomingWidget extends AppWidgetProvider { } } - private static void updateAppWidget(@NonNull Context context, @NonNull AppWidgetManager awm, int[] appWidgetIds) { + private static void updateAppWidget(@NonNull ExecutorService executor, @NonNull Context context, @NonNull AppWidgetManager awm, int[] appWidgetIds) { for (int appWidgetId : appWidgetIds) { - new Thread(() -> { + executor.submit(() -> { final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_upcoming); final Intent serviceIntent = new Intent(context, UpcomingWidgetService.class); @@ -131,7 +134,7 @@ public class UpcomingWidget extends AppWidgetProvider { awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.upcoming_widget_lv); awm.updateAppWidget(appWidgetId, views); - }).start(); + }); } } |