diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java index c5b4cf300..c909fa7f0 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java @@ -158,7 +158,7 @@ public class DelegateBase implements DlgClickNotify, protected void onPause() { m_isVisible = false; - XWServiceHelper.setListener( null ); + XWServiceHelper.clearListener( this ); m_dlgDelegate.onPausing(); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MultiService.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MultiService.java index 9e6bf8c16..98b295f4b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MultiService.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MultiService.java @@ -26,6 +26,9 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; +import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; import org.eehouse.android.xw4.loc.LocUtils; @@ -58,8 +61,8 @@ public class MultiService { private static final String ACTION_FETCH_DICT = "_afd"; private static final String FOR_MISSING_DICT = "_fmd"; - // Shouldn't this be a Set? - private MultiEventListener m_li; + private Set m_lis = Collections + .newSetFromMap(new ConcurrentHashMap()); // these do not currently pass between devices so they can change. public enum MultiEvent { _INVALID, @@ -100,28 +103,25 @@ public class MultiService { public void setListener( MultiEventListener li ) { - synchronized( this ) { - // If this is happening, the order of resume/pause isn't what we - // expect. Might need to keep a set of these instead of a - // singleton. - if ( BuildConfig.DEBUG ) { - if ( m_li == null && li == null ) { - Assert.fail(); - } else if ( m_li != null && li != null ) { - Assert.fail(); - } - } - m_li = li; - } + m_lis.add( li ); } - public void postEvent( MultiEvent event, Object ... args ) + public void clearListener( MultiEventListener li ) { - synchronized( this ) { - if ( null != m_li ) { - m_li.eventOccurred( event, args ); - } + Assert.assertTrue( m_lis.contains( li ) || ! BuildConfig.DEBUG ); + m_lis.remove( li ); + } + + public int postEvent( MultiEvent event, Object ... args ) + { + // don't just return size(): concurrency doesn't guarantee isn't + // changed + int count = 0; + for ( MultiEventListener listener : m_lis ) { + listener.eventOccurred( event, args ); + ++count; } + return count; } public static Intent makeMissingDictIntent( Context context, NetLaunchInfo nli, diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWServiceHelper.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWServiceHelper.java index a624dc047..5f6a3310e 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWServiceHelper.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/XWServiceHelper.java @@ -39,7 +39,7 @@ import java.util.Map; abstract class XWServiceHelper { private static final String TAG = XWServiceHelper.class.getSimpleName(); private Service mService; - private static MultiService s_srcMgr = null; + private static MultiService s_srcMgr = new MultiService(); public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED }; @@ -101,19 +101,17 @@ abstract class XWServiceHelper { public final static void setListener( MultiService.MultiEventListener li ) { - if ( null == s_srcMgr ) { - // DbgUtils.logf( "XWService.setListener: registering %s", - // li.getClass().getName() ); - s_srcMgr = new MultiService(); - } s_srcMgr.setListener( li ); } + public final static void clearListener( MultiService.MultiEventListener li ) + { + s_srcMgr.clearListener( li ); + } + protected void postEvent( MultiEvent event, Object ... args ) { - if ( null != s_srcMgr ) { - s_srcMgr.postEvent( event, args ); - } else { + if ( 0 == s_srcMgr.postEvent( event, args ) ) { Log.d( TAG, "postEvent(): dropping %s event", event.toString() ); }