From 386c28e5963c55499ae2e1e11594f1158fd28f64 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 1 Mar 2014 15:17:14 -0800 Subject: [PATCH] don't notify network change listeners unless a change is in fact a change and until there's been two seconds without changes. There's a lot of connection up-and-down spam when connecting and maybe with iffy connectivity, and no point in passing that through to code that will do stuff like stopping a send thread in response. --- .../eehouse/android/xw4/NetStateCache.java | 64 +++++++++++++++---- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java index 7fb3875b4..89651ba3d 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetStateCache.java @@ -24,14 +24,17 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.net.NetworkInfo; import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.os.Handler; import java.util.HashSet; import java.util.Iterator; -import android.os.Build; + import junit.framework.Assert; public class NetStateCache { + private static final long WAIT_STABLE_MILLIS = 2 * 1000; public interface StateChangedIf { public void netAvail( boolean nowAvailable ); @@ -40,7 +43,7 @@ public class NetStateCache { private static Boolean s_haveReceiver = new Boolean( false ); private static HashSet s_ifs; private static boolean s_netAvail = false; - private static CommsBroadcastReceiver s_receiver; + private static PvtBroadcastReceiver s_receiver; private static final boolean s_onSim = Build.PRODUCT.contains("sdk"); public static void register( Context context, StateChangedIf proc ) @@ -78,7 +81,7 @@ public class NetStateCache { s_netAvail = ni != null && ni.isAvailable() && ni.isConnected(); - s_receiver = new CommsBroadcastReceiver(); + s_receiver = new PvtBroadcastReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION ); @@ -91,17 +94,30 @@ public class NetStateCache { } } - private static class CommsBroadcastReceiver extends BroadcastReceiver { + private static class PvtBroadcastReceiver extends BroadcastReceiver { + private Runnable mNotifyLater; + private Handler mHandler; + private boolean mLastStateSent; + + public PvtBroadcastReceiver() + { + DbgUtils.assertOnUIThread(); + mHandler = new Handler(); + mLastStateSent = s_netAvail; + } + @Override public void onReceive( Context context, Intent intent ) { + DbgUtils.assertOnUIThread(); + if ( intent.getAction(). equals( ConnectivityManager.CONNECTIVITY_ACTION)) { NetworkInfo ni = (NetworkInfo)intent. getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); NetworkInfo.State state = ni.getState(); - DbgUtils.logf( "CommsBroadcastReceiver.onReceive: " + DbgUtils.logf( "PvtBroadcastReceiver.onReceive: " + "new network state: %s", state.toString() ); boolean netAvail; @@ -119,16 +135,38 @@ public class NetStateCache { } if ( s_netAvail != netAvail ) { - s_netAvail = netAvail; - Iterator iter = s_ifs.iterator(); - while ( iter.hasNext() ) { - StateChangedIf proc = iter.next(); - proc.netAvail( netAvail ); + s_netAvail = netAvail; // keep current in case we're asked + + // We want to wait for WAIT_STABLE_MILLIS of inactivity + // before informing listeners. So each time there's a + // change, kill any existing timer then set another, which + // will only fire if we go that long without coming + // through here again. + + if ( null != mNotifyLater ) { + mHandler.removeCallbacks( mNotifyLater ); + mNotifyLater = null; + } + if ( mLastStateSent != s_netAvail ) { + mNotifyLater = new Runnable() { + @Override + public void run() { + DbgUtils.logf( "PvtBroadcastReceiver: run() fired." ); + Assert.assertTrue( mLastStateSent != s_netAvail ); + mLastStateSent = s_netAvail; + synchronized( s_ifs ) { + Iterator iter = s_ifs.iterator(); + while ( iter.hasNext() ) { + iter.next().netAvail( s_netAvail ); + } + } + } + }; + mHandler.postDelayed( mNotifyLater, WAIT_STABLE_MILLIS ); } } } } - } // class CommsBroadcastReceiver + } // class PvtBroadcastReceiver } -