diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 00627ef381ab3..ae8a2cbf51206 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -31,7 +31,6 @@ import android.os.Parcelable; import android.os.RemoteException; import android.os.WorkSource; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.Log; import android.util.proto.ProtoOutputStream; @@ -40,6 +39,8 @@ import libcore.timezone.ZoneInfoDb; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.WeakHashMap; /** * This class provides access to the system alarm services. These allow you @@ -222,26 +223,12 @@ public class AlarmManager { } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } - - synchronized (AlarmManager.class) { - if (sWrappers != null) { - sWrappers.remove(mListener); - } - } } @Override public void doAlarm(IAlarmCompleteListener alarmManager) { mCompletion = alarmManager; - // Remove this listener from the wrapper cache first; the server side - // already considers it gone - synchronized (AlarmManager.class) { - if (sWrappers != null) { - sWrappers.remove(mListener); - } - } - mHandler.post(this); } @@ -263,9 +250,14 @@ public class AlarmManager { } } - // Tracking of the OnAlarmListener -> wrapper mapping, for cancel() support. - // Access is synchronized on the AlarmManager class object. - private static ArrayMap sWrappers; + /** + * Tracking of the OnAlarmListener -> ListenerWrapper mapping, for cancel() support. + * An entry is guaranteed to stay in this map as long as its ListenerWrapper is held by the + * server. + * + *

Access is synchronized on the AlarmManager class object. + */ + private static WeakHashMap> sWrappers; /** * package private on purpose @@ -682,14 +674,17 @@ public class AlarmManager { if (listener != null) { synchronized (AlarmManager.class) { if (sWrappers == null) { - sWrappers = new ArrayMap(); + sWrappers = new WeakHashMap<>(); } - recipientWrapper = sWrappers.get(listener); + final WeakReference weakRef = sWrappers.get(listener); + if (weakRef != null) { + recipientWrapper = weakRef.get(); + } // no existing wrapper => build a new one if (recipientWrapper == null) { recipientWrapper = new ListenerWrapper(listener); - sWrappers.put(listener, recipientWrapper); + sWrappers.put(listener, new WeakReference<>(recipientWrapper)); } } @@ -948,7 +943,10 @@ public class AlarmManager { ListenerWrapper wrapper = null; synchronized (AlarmManager.class) { if (sWrappers != null) { - wrapper = sWrappers.get(listener); + final WeakReference weakRef = sWrappers.get(listener); + if (weakRef != null) { + wrapper = weakRef.get(); + } } }