cleanup around posting alerts; skip back-stack

Had to disable use of the back-stack for DialogFragments, though that
means I can't prevent duplicates from stacking up (esp. in the
pathological robot-vs-robot case, but also just when I rotate the device
while a "rematch" alert is up.) The problem seems to be in dismiss
actions being handled too late. One easy-to-duplicate case is the
tile-picker. When it's enabled and you commit a turn I post first the
confirmation and then, in response to a "yes", the picker. But the
picker gets added to the stack moments before the confirmation is
removed, and it's the nature of stack removal that everything above
what's being removed gets pulled too. So you never see the
picker. Simply post()ing a runnable to put the picker up later fixes
this one case, but a similar trick doesn't work elsewhere, so I'm
punting until I have time to root-cause the problem.
This commit is contained in:
Eric House 2017-04-13 08:18:07 -07:00
parent 3bff16193a
commit 269fceddf2
6 changed files with 50 additions and 25 deletions

View file

@ -1747,23 +1747,34 @@ public class BoardDelegate extends DelegateBase
// This is supposed to be called from the jni thread // This is supposed to be called from the jni thread
@Override @Override
public void notifyPickTileBlank( int playerNum, int col, int row, String[] texts ) public void notifyPickTileBlank( int playerNum, int col, int row,
String[] texts )
{ {
TilePickAlert.TilePickState tps = final TilePickAlert.TilePickState tps =
new TilePickAlert.TilePickState( playerNum, texts, col, row ); new TilePickAlert.TilePickState( playerNum, texts, col, row );
runOnUiThread( new Runnable() {
@Override
public void run() {
show( TilePickAlert.newInstance( Action.BLANK_PICKED, tps ) ); show( TilePickAlert.newInstance( Action.BLANK_PICKED, tps ) );
} }
} );
}
@Override @Override
public void informNeedPickTiles( boolean isInitial, public void informNeedPickTiles( boolean isInitial,
int playerNum, int nToPick, int playerNum, int nToPick,
String[] texts, int[] counts ) String[] texts, int[] counts )
{ {
TilePickAlert.TilePickState tps final TilePickAlert.TilePickState tps
= new TilePickAlert.TilePickState( isInitial, playerNum, nToPick, = new TilePickAlert.TilePickState( isInitial, playerNum, nToPick,
texts, counts ); texts, counts );
runOnUiThread( new Runnable() {
@Override
public void run() {
show( TilePickAlert.newInstance( Action.TRAY_PICKED, tps ) ); show( TilePickAlert.newInstance( Action.TRAY_PICKED, tps ) );
} }
} );
}
@Override @Override
public void informNeedPassword( int player, String name ) public void informNeedPassword( int player, String name )

View file

@ -436,8 +436,9 @@ public class DelegateBase implements DlgClickNotify,
return null; return null;
} }
protected void showDialogFragment( DlgID dlgID, Object... params ) protected void showDialogFragment( DlgID dlgID, final Object... params )
{ {
DbgUtils.assertOnUIThread();
show( DBAlert.newInstance( dlgID, params ) ); show( DBAlert.newInstance( dlgID, params ) );
} }
@ -469,6 +470,7 @@ public class DelegateBase implements DlgClickNotify,
protected void show( XWDialogFragment df ) protected void show( XWDialogFragment df )
{ {
DbgUtils.assertOnUIThread();
if ( m_activity instanceof XWActivity ) { if ( m_activity instanceof XWActivity ) {
((XWActivity)m_activity).show( df ); ((XWActivity)m_activity).show( df );
} else if ( m_activity instanceof PrefsActivity ) { } else if ( m_activity instanceof PrefsActivity ) {
@ -668,8 +670,7 @@ public class DelegateBase implements DlgClickNotify,
public boolean onPosButton( Action action, Object[] params ) public boolean onPosButton( Action action, Object[] params )
{ {
boolean handled = true; boolean handled = true;
Log.d( TAG, "%s.posButtonClicked(%s)", getClass().getSimpleName(), Log.d( TAG, "%s.onPosButton(%s)", getClass().getSimpleName(), action );
action.toString() );
switch( action ) { switch( action ) {
case ENABLE_SMS_ASK: case ENABLE_SMS_ASK:
showSMSEnableDialog( Action.ENABLE_SMS_DO ); showSMSEnableDialog( Action.ENABLE_SMS_DO );

View file

@ -74,12 +74,12 @@ abstract class DlgDelegateAlert extends XWDialogFragment {
@Override @Override
public void onDismiss( DialogInterface dif ) public void onDismiss( DialogInterface dif )
{ {
super.onDismiss( dif );
Activity activity = getActivity(); Activity activity = getActivity();
if ( activity instanceof DlgClickNotify ) { if ( activity instanceof DlgClickNotify ) {
((DlgClickNotify)activity) ((DlgClickNotify)activity)
.onDismissed( m_state.m_action, m_state.m_params ); .onDismissed( m_state.m_action, m_state.m_params );
} }
super.onDismiss( dif );
} }
@Override @Override
@ -108,7 +108,7 @@ abstract class DlgDelegateAlert extends XWDialogFragment {
@Override @Override
public void onClick( DialogInterface dlg, int button ) { public void onClick( DialogInterface dlg, int button ) {
checkNotAgainCheck( m_state, naView ); checkNotAgainCheck( m_state, naView );
XWActivity xwact = (XWActivity)getActivity(); DlgClickNotify xwact = (DlgClickNotify)getActivity();
xwact.onPosButton( pair.action, m_state.m_params ); xwact.onPosButton( pair.action, m_state.m_params );
} }
}; };

View file

@ -130,6 +130,7 @@ public class MainActivity extends XWActivity
if ( m_safeToCommit ) { if ( m_safeToCommit ) {
handled = dispatchNewIntentImpl( intent ); handled = dispatchNewIntentImpl( intent );
} else { } else {
DbgUtils.assertOnUIThread();
m_runWhenSafe.add( new Runnable() { m_runWhenSafe.add( new Runnable() {
@Override @Override
public void run() { public void run() {
@ -300,7 +301,7 @@ public class MainActivity extends XWActivity
protected void finishFragment() protected void finishFragment()
{ {
// Assert.assertTrue( fragment instanceof XWFragment ); // Assert.assertTrue( fragment instanceof XWFragment );
// DbgUtils.logf( "MainActivity.finishFragment(%s)", fragment.toString() ); // Log.d( TAG, "finishFragment()" );
getSupportFragmentManager().popBackStack/*Immediate*/(); getSupportFragmentManager().popBackStack/*Immediate*/();
} }
@ -465,6 +466,7 @@ public class MainActivity extends XWActivity
if ( m_safeToCommit ) { if ( m_safeToCommit ) {
safeAddFragment( fragment, parentName ); safeAddFragment( fragment, parentName );
} else { } else {
DbgUtils.assertOnUIThread();
m_runWhenSafe.add( new Runnable() { m_runWhenSafe.add( new Runnable() {
@Override @Override
public void run() { public void run() {
@ -516,6 +518,7 @@ public class MainActivity extends XWActivity
private void setSafeToRun() private void setSafeToRun()
{ {
DbgUtils.assertOnUIThread();
m_safeToCommit = true; m_safeToCommit = true;
for ( Runnable proc : m_runWhenSafe ) { for ( Runnable proc : m_runWhenSafe ) {
proc.run(); proc.run();

View file

@ -285,20 +285,27 @@ public class XWActivity extends FragmentActivity
{ {
FragmentManager fm = getSupportFragmentManager(); FragmentManager fm = getSupportFragmentManager();
String tag = df.getFragTag(); String tag = df.getFragTag();
if ( true ) {
df.show( fm, tag );
} else {
Log.d( TAG, "%s.show(%s) called; tag: %s", getClass().getSimpleName(), Log.d( TAG, "%s.show(%s) called; tag: %s", getClass().getSimpleName(),
df.getClass().getSimpleName(), tag ); df.getClass().getSimpleName(), tag );
FragmentTransaction trans = fm.beginTransaction(); FragmentTransaction trans = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag( tag ); Fragment prev = fm.findFragmentByTag( tag );
if ( null != prev && prev instanceof DialogFragment ) { if ( null != prev && prev instanceof DialogFragment ) {
Log.d( TAG, "removing %s (tag %s)", Log.d( TAG, "show(): removing %s (tag %s)",
prev.getClass().getSimpleName(), tag ); prev.getClass().getSimpleName(), tag );
((DialogFragment)prev).dismiss(); ((DialogFragment)prev).dismiss();
} else {
Log.d( TAG, "show(): NOT removing or didn't find for tag %s)", tag );
} }
trans.addToBackStack( tag ); trans.addToBackStack( tag );
// Create and show the dialog. show() commits the transaction // Create and show the dialog. show() commits the transaction
df.show( trans, tag ); df.show( trans, tag );
} }
}
protected Dialog makeDialog( DBAlert alert, Object[] params ) protected Dialog makeDialog( DBAlert alert, Object[] params )
{ {

View file

@ -72,19 +72,22 @@ abstract class XWDialogFragment extends DialogFragment {
@Override @Override
public void onCancel( DialogInterface dialog ) public void onCancel( DialogInterface dialog )
{ {
super.onCancel( dialog );
// Log.d( TAG, "%s.onCancel() called", getClass().getSimpleName() );
if ( null != m_onCancel ) { if ( null != m_onCancel ) {
m_onCancel.onCancelled( this ); m_onCancel.onCancelled( this );
} }
super.onCancel( dialog );
} }
@Override @Override
public void onDismiss( DialogInterface dif ) public void onDismiss( DialogInterface dif )
{ {
// Log.d( TAG, "%s.onDismiss() called", getClass().getSimpleName() );
super.onDismiss( dif );
if ( null != m_onDismiss ) { if ( null != m_onDismiss ) {
m_onDismiss.onDismissed( this ); m_onDismiss.onDismissed( this );
} }
super.onDismiss( dif );
} }
abstract String getFragTag(); abstract String getFragTag();