diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 1b22c84fe3..cc0a68612d 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -218,8 +218,6 @@ public class QuickstepLauncher extends Launcher { private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController; private SplitToWorkspaceController mSplitToWorkspaceController; - private AsyncClockEventDelegate mAsyncClockEventDelegate; - /** * If Launcher restarted while in the middle of an Overview split select, it needs this data to * recover. In all other cases this will remain null. @@ -497,10 +495,6 @@ public class QuickstepLauncher extends Launcher { mSplitSelectStateController.onDestroy(); } - if (mAsyncClockEventDelegate != null) { - mAsyncClockEventDelegate.onDestroy(); - } - super.onDestroy(); mHotseatPredictionController.destroy(); mSplitWithKeyboardShortcutController.onDestroy(); @@ -1346,18 +1340,12 @@ public class QuickstepLauncher extends Launcher { switch (name) { case "TextClock", "android.widget.TextClock" -> { TextClock tc = new TextClock(context, attrs); - if (mAsyncClockEventDelegate == null) { - mAsyncClockEventDelegate = new AsyncClockEventDelegate(this); - } - tc.setClockEventDelegate(mAsyncClockEventDelegate); + tc.setClockEventDelegate(AsyncClockEventDelegate.INSTANCE.get(this)); return tc; } case "AnalogClock", "android.widget.AnalogClock" -> { AnalogClock ac = new AnalogClock(context, attrs); - if (mAsyncClockEventDelegate == null) { - mAsyncClockEventDelegate = new AsyncClockEventDelegate(this); - } - ac.setClockEventDelegate(mAsyncClockEventDelegate); + ac.setClockEventDelegate(AsyncClockEventDelegate.INSTANCE.get(this)); return ac; } } diff --git a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java index 0dee5b3103..cda87c0f36 100644 --- a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java +++ b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java @@ -32,6 +32,8 @@ import android.widget.TextClock.ClockEventDelegate; import androidx.annotation.WorkerThread; +import com.android.launcher3.util.MainThreadInitializedObject; +import com.android.launcher3.util.SafeCloseable; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.SettingsCache.OnChangeListener; import com.android.launcher3.util.SimpleBroadcastReceiver; @@ -42,7 +44,11 @@ import java.util.List; /** * Extension of {@link ClockEventDelegate} to support async event registration */ -public class AsyncClockEventDelegate extends ClockEventDelegate implements OnChangeListener { +public class AsyncClockEventDelegate extends ClockEventDelegate + implements OnChangeListener, SafeCloseable { + + public static final MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(AsyncClockEventDelegate::new); private final Context mContext; private final SimpleBroadcastReceiver mReceiver = @@ -55,7 +61,7 @@ public class AsyncClockEventDelegate extends ClockEventDelegate implements OnCha private boolean mFormatRegistered = false; private boolean mDestroyed = false; - public AsyncClockEventDelegate(Context context) { + private AsyncClockEventDelegate(Context context) { super(context); mContext = context; @@ -79,6 +85,9 @@ public class AsyncClockEventDelegate extends ClockEventDelegate implements OnCha @Override public void registerFormatChangeObserver(ContentObserver observer, int userHandle) { + if (mDestroyed) { + return; + } synchronized (mFormatObservers) { if (!mFormatRegistered && !mDestroyed) { SettingsCache.INSTANCE.get(mContext).register(mFormatUri, this); @@ -114,10 +123,8 @@ public class AsyncClockEventDelegate extends ClockEventDelegate implements OnCha } } - /** - * Unregisters all system callbacks and destroys this delegate - */ - public void onDestroy() { + @Override + public void close() { mDestroyed = true; SettingsCache.INSTANCE.get(mContext).unregister(mFormatUri, this); UI_HELPER_EXECUTOR.execute(() -> mReceiver.unregisterReceiverSafely(mContext));