rewrite DictsActivity to not crash when un- and re-loaded: make

dialogs depend only on bundleable ivars -- ints and strings, not Views
-- and bundle them.  Don't use onPrepareDialog, only onCreateDialog,
and so call removeDialog() every time one's dismissed.  Do some
refactoring to support this.
This commit is contained in:
Andy2 2011-08-23 18:41:19 -07:00
parent 84e61f3b3f
commit 7da5b24e0f
7 changed files with 149 additions and 101 deletions

View file

@ -157,7 +157,7 @@ public class BoardActivity extends XWActivity
ab.setNegativeButton( R.string.button_retry, lstnr ); ab.setNegativeButton( R.string.button_retry, lstnr );
} }
dialog = ab.create(); dialog = ab.create();
setRemoveOnDismiss( dialog, id ); Utils.setRemoveOnDismiss( this, dialog, id );
break; break;
case DLG_DELETED: case DLG_DELETED:

View file

@ -61,6 +61,12 @@ public class DictsActivity extends ExpandableListActivity
private static final String DICT_DOLAUNCH = "do_launch"; private static final String DICT_DOLAUNCH = "do_launch";
private static final String DICT_LANG_EXTRA = "use_lang"; private static final String DICT_LANG_EXTRA = "use_lang";
private static final String DICT_NAME_EXTRA = "use_dict"; private static final String DICT_NAME_EXTRA = "use_dict";
private static final String PACKED_POSITION = "packed_position";
private static final String NAME = "name";
private static final String LANG = "lang";
private static final String MOVEFROMLOC = "movefromloc";
private static final String MOVETOLOC = "movetoloc";
private static final int PICK_STORAGE = DlgDelegate.DIALOG_LAST + 1; private static final int PICK_STORAGE = DlgDelegate.DIALOG_LAST + 1;
private static final int MOVE_DICT = DlgDelegate.DIALOG_LAST + 2; private static final int MOVE_DICT = DlgDelegate.DIALOG_LAST + 2;
@ -72,17 +78,18 @@ public class DictsActivity extends ExpandableListActivity
private ExpandableListView m_expView; private ExpandableListView m_expView;
private DlgDelegate m_delegate; private DlgDelegate m_delegate;
private String[] m_locNames; private String[] m_locNames;
private DictListAdapter m_adapter;
private XWListItem m_rowView; private long m_packedPosition;
GameUtils.DictLoc m_moveFromLoc; private GameUtils.DictLoc m_moveFromLoc;
GameUtils.DictLoc m_moveToLoc; private GameUtils.DictLoc m_moveToLoc;
private SDCardWatcher m_cardWatcher; private SDCardWatcher m_cardWatcher;
private String m_moveName;
private LayoutInflater m_factory; private LayoutInflater m_factory;
private class DictListAdapter implements ExpandableListAdapter { private class DictListAdapter implements ExpandableListAdapter {
private Context m_context; private Context m_context;
private XWListItem[][] m_cache;
public DictListAdapter( Context context ) { public DictListAdapter( Context context ) {
//super( context, m_dicts.length ); //super( context, m_dicts.length );
@ -105,29 +112,41 @@ public class DictsActivity extends ExpandableListActivity
boolean isLastChild, View convertView, boolean isLastChild, View convertView,
ViewGroup parent) ViewGroup parent)
{ {
int lang = (int)getGroupId( groupPosition ); return getChildView( groupPosition, childPosition );
String[] dicts = DictLangCache.getHaveLang( m_context, lang ); }
String text;
boolean canDelete = false; private View getChildView( int groupPosition, int childPosition )
if ( null != dicts && childPosition < dicts.length ) { {
text = dicts[childPosition]; XWListItem view = null;
canDelete = !GameUtils.dictIsBuiltin( DictsActivity.this, if ( null != m_cache && null != m_cache[groupPosition] ) {
text ); view = m_cache[groupPosition][childPosition];
} else {
text = m_download;
}
XWListItem view =
(XWListItem)m_factory.inflate( R.layout.list_item, null );
view.setText( text );
if ( canDelete ) {
view.setDeleteCallback( DictsActivity.this );
} }
GameUtils.DictLoc loc = if ( null == view ) {
GameUtils.getDictLoc( DictsActivity.this, text ); int lang = (int)getGroupId( groupPosition );
view.setComment( m_locNames[loc.ordinal()] ); String[] dicts = DictLangCache.getHaveLang( m_context, lang );
view.cache( loc ); String text;
boolean canDelete = false;
if ( null != dicts && childPosition < dicts.length ) {
text = dicts[childPosition];
canDelete = !GameUtils.dictIsBuiltin( DictsActivity.this,
text );
} else {
text = m_download;
}
view = (XWListItem)m_factory.inflate( R.layout.list_item, null );
view.setText( text );
if ( canDelete ) {
view.setDeleteCallback( DictsActivity.this );
}
GameUtils.DictLoc loc =
GameUtils.getDictLoc( DictsActivity.this, text );
view.setComment( m_locNames[loc.ordinal()] );
view.cache( loc );
addToCache( groupPosition, childPosition, view );
}
return view; return view;
} }
@ -188,17 +207,40 @@ public class DictsActivity extends ExpandableListActivity
public void onGroupExpanded(int groupPosition){} public void onGroupExpanded(int groupPosition){}
public void registerDataSetObserver( DataSetObserver obs ){} public void registerDataSetObserver( DataSetObserver obs ){}
public void unregisterDataSetObserver( DataSetObserver obs ){} public void unregisterDataSetObserver( DataSetObserver obs ){}
protected XWListItem getSelChildView()
{
int groupPosition =
ExpandableListView.getPackedPositionGroup( m_packedPosition );
int childPosition =
ExpandableListView.getPackedPositionChild( m_packedPosition );
return (XWListItem)getChildView( groupPosition, childPosition );
}
private void addToCache( int group, int child, XWListItem view )
{
if ( null == m_cache ) {
m_cache = new XWListItem[getGroupCount()][];
}
if ( null == m_cache[group] ) {
m_cache[group] = new XWListItem[getChildrenCount(group)];
}
Assert.assertTrue( null == m_cache[group][child] );
m_cache[group][child] = view;
}
} }
@Override @Override
protected Dialog onCreateDialog( int id ) protected Dialog onCreateDialog( int id )
{ {
Dialog dialog;
DialogInterface.OnClickListener lstnr; DialogInterface.OnClickListener lstnr;
Dialog dialog;
String format;
String message;
boolean doRemove = true;
switch( id ) { switch( id ) {
case PICK_STORAGE: case PICK_STORAGE:
lstnr = new DialogInterface.OnClickListener() { lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) { public void onClick( DialogInterface dlg, int item ) {
startDownload( m_lang, m_name, item != startDownload( m_lang, m_name, item !=
@ -216,21 +258,28 @@ public class DictsActivity extends ExpandableListActivity
case MOVE_DICT: case MOVE_DICT:
lstnr = new DialogInterface.OnClickListener() { lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) { public void onClick( DialogInterface dlg, int item ) {
XWListItem rowView = m_adapter.getSelChildView();
if ( GameUtils.moveDict( DictsActivity.this, if ( GameUtils.moveDict( DictsActivity.this,
m_moveName, rowView.getText(),
m_moveFromLoc, m_moveFromLoc,
m_moveToLoc ) ) { m_moveToLoc ) ) {
m_rowView. rowView.
setComment( m_locNames[m_moveToLoc.ordinal()]); setComment( m_locNames[m_moveToLoc.ordinal()]);
m_rowView.cache( m_moveToLoc ); rowView.cache( m_moveToLoc );
m_rowView.invalidate(); rowView.invalidate();
} else { } else {
Utils.logf( "moveDict failed" ); Utils.logf( "moveDict failed" );
} }
} }
}; };
format = getString( R.string.move_dictf );
message = String.format( format,
m_adapter.getSelChildView().getText(),
m_locNames[ m_moveFromLoc.ordinal() ],
m_locNames[ m_moveToLoc.ordinal() ] );
dialog = new AlertDialog.Builder( this ) dialog = new AlertDialog.Builder( this )
.setMessage( "" ) // will set later .setMessage( message )
.setPositiveButton( R.string.button_ok, lstnr ) .setPositiveButton( R.string.button_ok, lstnr )
.setNegativeButton( R.string.button_cancel, null ) .setNegativeButton( R.string.button_cancel, null )
.create(); .create();
@ -240,18 +289,22 @@ public class DictsActivity extends ExpandableListActivity
public void onClick( DialogInterface dlg, int item ) { public void onClick( DialogInterface dlg, int item ) {
if ( DialogInterface.BUTTON_NEGATIVE == item if ( DialogInterface.BUTTON_NEGATIVE == item
|| DialogInterface.BUTTON_POSITIVE == item ) { || DialogInterface.BUTTON_POSITIVE == item ) {
setDefault( R.string.key_default_dict, m_rowView ); setDefault( R.string.key_default_dict );
} }
if ( DialogInterface.BUTTON_NEGATIVE == item if ( DialogInterface.BUTTON_NEGATIVE == item
|| DialogInterface.BUTTON_NEUTRAL == item ) { || DialogInterface.BUTTON_NEUTRAL == item ) {
setDefault( R.string.key_default_robodict, setDefault( R.string.key_default_robodict );
m_rowView );
} }
} }
}; };
XWListItem rowView = m_adapter.getSelChildView();
String lang =
DictLangCache.getLangName( this, rowView.getText() );
format = getString( R.string.set_default_messagef );
message = String.format( format, lang );
dialog = new AlertDialog.Builder( this ) dialog = new AlertDialog.Builder( this )
.setTitle( R.string.query_title ) .setTitle( R.string.query_title )
.setMessage( "" ) // or can't change it later! .setMessage( message )
.setPositiveButton( R.string.button_default_human, lstnr ) .setPositiveButton( R.string.button_default_human, lstnr )
.setNeutralButton( R.string.button_default_robot, lstnr ) .setNeutralButton( R.string.button_default_robot, lstnr )
.setNegativeButton( R.string.button_default_both, lstnr ) .setNegativeButton( R.string.button_default_both, lstnr )
@ -259,44 +312,22 @@ public class DictsActivity extends ExpandableListActivity
break; break;
default: default:
dialog = m_delegate.onCreateDialog( id ); dialog = m_delegate.onCreateDialog( id );
doRemove = false;
break; break;
} }
if ( doRemove && null != dialog ) {
Utils.setRemoveOnDismiss( this, dialog, id );
}
return dialog; return dialog;
} } // onCreateDialog
@Override
public void onPrepareDialog( int id, Dialog dialog )
{
AlertDialog ad = (AlertDialog)dialog;
String format;
String message;
switch( id ) {
case PICK_STORAGE:
break;
case MOVE_DICT:
format = getString( R.string.move_dictf );
message = String.format( format, m_moveName,
m_locNames[ m_moveFromLoc.ordinal() ],
m_locNames[ m_moveToLoc.ordinal() ] );
ad.setMessage( message );
break;
case SET_DEFAULT:
String lang =
DictLangCache.getLangName( this, m_rowView.getText() );
format = getString( R.string.set_default_messagef );
message = String.format( format, lang );
ad.setMessage( message );
break;
default:
m_delegate.onPrepareDialog( id, dialog );
}
}
@Override @Override
protected void onCreate( Bundle savedInstanceState ) protected void onCreate( Bundle savedInstanceState )
{ {
super.onCreate( savedInstanceState ); super.onCreate( savedInstanceState );
getBundledData( savedInstanceState );
Resources res = getResources(); Resources res = getResources();
m_locNames = res.getStringArray( R.array.loc_names ); m_locNames = res.getStringArray( R.array.loc_names );
@ -343,8 +374,37 @@ public class DictsActivity extends ExpandableListActivity
{ {
super.onSaveInstanceState( outState ); super.onSaveInstanceState( outState );
m_delegate.onSaveInstanceState( outState ); m_delegate.onSaveInstanceState( outState );
outState.putLong( PACKED_POSITION, m_packedPosition );
outState.putString( NAME, m_name );
outState.putInt( LANG, m_lang );
if ( null != m_moveFromLoc ) {
outState.putInt( MOVEFROMLOC, m_moveFromLoc.ordinal() );
}
if ( null != m_moveToLoc ) {
outState.putInt( MOVETOLOC, m_moveToLoc.ordinal() );
}
} }
private void getBundledData( Bundle savedInstanceState )
{
if ( null != savedInstanceState ) {
m_packedPosition = savedInstanceState.getLong( PACKED_POSITION );
m_name = savedInstanceState.getString( NAME );
m_lang = savedInstanceState.getInt( LANG );
int tmp = savedInstanceState.getInt( MOVEFROMLOC, -1 );
if ( -1 != tmp ) {
m_moveFromLoc = GameUtils.DictLoc.values()[tmp];
}
tmp = savedInstanceState.getInt( MOVETOLOC, -1 );
if ( -1 != tmp ) {
m_moveToLoc = GameUtils.DictLoc.values()[tmp];
}
}
}
@Override
protected void onPause() { protected void onPause() {
m_cardWatcher.close(); m_cardWatcher.close();
m_cardWatcher = null; m_cardWatcher = null;
@ -402,14 +462,14 @@ public class DictsActivity extends ExpandableListActivity
return false; return false;
} }
XWListItem row = (XWListItem)info.targetView; m_packedPosition = info.packedPosition;
int id = item.getItemId(); int id = item.getItemId();
switch( id ) { switch( id ) {
case R.id.dicts_item_move: case R.id.dicts_item_move:
askMoveDict( row ); askMoveDict( (XWListItem)info.targetView );
break; break;
case R.id.dicts_item_select: case R.id.dicts_item_select:
m_rowView = row;
showDialog( SET_DEFAULT ); showDialog( SET_DEFAULT );
break; break;
case R.id.dicts_item_details: case R.id.dicts_item_details:
@ -420,13 +480,14 @@ public class DictsActivity extends ExpandableListActivity
return handled; return handled;
} }
private void setDefault( int keyId, final XWListItem text ) private void setDefault( int keyId )
{ {
XWListItem view = m_adapter.getSelChildView();
SharedPreferences sp SharedPreferences sp
= PreferenceManager.getDefaultSharedPreferences( this ); = PreferenceManager.getDefaultSharedPreferences( this );
SharedPreferences.Editor editor = sp.edit(); SharedPreferences.Editor editor = sp.edit();
String key = getString( keyId ); String key = getString( keyId );
String name = text.getText(); String name = view.getText();
editor.putString( key, name ); editor.putString( key, name );
editor.commit(); editor.commit();
} }
@ -436,14 +497,12 @@ public class DictsActivity extends ExpandableListActivity
// options for YY? // options for YY?
private void askMoveDict( XWListItem item ) private void askMoveDict( XWListItem item )
{ {
m_rowView = item;
m_moveFromLoc = (GameUtils.DictLoc)item.getCached(); m_moveFromLoc = (GameUtils.DictLoc)item.getCached();
if ( m_moveFromLoc == GameUtils.DictLoc.INTERNAL ) { if ( m_moveFromLoc == GameUtils.DictLoc.INTERNAL ) {
m_moveToLoc = GameUtils.DictLoc.EXTERNAL; m_moveToLoc = GameUtils.DictLoc.EXTERNAL;
} else { } else {
m_moveToLoc = GameUtils.DictLoc.INTERNAL; m_moveToLoc = GameUtils.DictLoc.INTERNAL;
} }
m_moveName = item.getText();
showDialog( MOVE_DICT ); showDialog( MOVE_DICT );
} }
@ -515,9 +574,8 @@ public class DictsActivity extends ExpandableListActivity
private void mkListAdapter() private void mkListAdapter()
{ {
m_langs = DictLangCache.listLangs( this ); m_langs = DictLangCache.listLangs( this );
//m_langs = DictLangCache.getLangNames( this ); m_adapter = new DictListAdapter( this );
ExpandableListAdapter adapter = new DictListAdapter( this ); setListAdapter( m_adapter );
setListAdapter( adapter );
} }
private void expandGroups() private void expandGroups()

View file

@ -93,17 +93,6 @@ public class DlgDelegate {
return dialog; return dialog;
} }
protected void setRemoveOnDismiss( Dialog dialog, final int id )
{
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
public void onDismiss( DialogInterface di ) {
Utils.logf( "%s.onDismiss() called",
getClass().getName() );
m_activity.removeDialog( id );
}
} );
}
public void onPrepareDialog( int id, Dialog dialog ) public void onPrepareDialog( int id, Dialog dialog )
{ {
AlertDialog ad = (AlertDialog)dialog; AlertDialog ad = (AlertDialog)dialog;

View file

@ -124,7 +124,7 @@ public class GamesList extends XWListActivity
ab.setNeutralButton( R.string.button_substdict, lstnr ); ab.setNeutralButton( R.string.button_substdict, lstnr );
} }
dialog = ab.create(); dialog = ab.create();
setRemoveOnDismiss( dialog, id ); Utils.setRemoveOnDismiss( this, dialog, id );
break; break;
case SHOW_SUBST: case SHOW_SUBST:
m_sameLangDicts = m_sameLangDicts =

View file

@ -22,14 +22,15 @@ package org.eehouse.android.xw4;
import android.util.Log; import android.util.Log;
import java.lang.Thread; import java.lang.Thread;
import android.widget.Toast; import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.app.Activity; import android.widget.Toast;
import android.app.Dialog;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -105,6 +106,16 @@ public class Utils {
Toast.makeText( context, text, Toast.LENGTH_SHORT).show(); Toast.makeText( context, text, Toast.LENGTH_SHORT).show();
} }
public static void setRemoveOnDismiss( final Activity activity,
Dialog dialog, final int id )
{
dialog.setOnDismissListener( new DialogInterface.OnDismissListener() {
public void onDismiss( DialogInterface di ) {
activity.removeDialog( id );
}
} );
}
public static View inflate( Context context, int layoutId ) public static View inflate( Context context, int layoutId )
{ {
LayoutInflater factory = LayoutInflater.from( context ); LayoutInflater factory = LayoutInflater.from( context );

View file

@ -100,11 +100,6 @@ public class XWActivity extends Activity {
return dialog; return dialog;
} }
protected void setRemoveOnDismiss( Dialog dialog, int id )
{
m_delegate.setRemoveOnDismiss( dialog, id );
}
@Override @Override
protected void onPrepareDialog( int id, Dialog dialog ) protected void onPrepareDialog( int id, Dialog dialog )
{ {

View file

@ -105,11 +105,6 @@ public class XWListActivity extends ListActivity {
return dialog; return dialog;
} }
protected void setRemoveOnDismiss( Dialog dialog, int id )
{
m_delegate.setRemoveOnDismiss( dialog, id );
}
@Override @Override
protected void onPrepareDialog( int id, Dialog dialog ) protected void onPrepareDialog( int id, Dialog dialog )
{ {