diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml
index afab3c234..26d7cef01 100644
--- a/xwords4/android/XWords4/res/values/strings.xml
+++ b/xwords4/android/XWords4/res/values/strings.xml
@@ -1819,4 +1819,6 @@
version: \"%s\"; and make/model of your phone or
tablet.)"
+ Scanning %s
+
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseActivity.java
index 38a3d49f9..cf47c665b 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseActivity.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictBrowseActivity.java
@@ -20,9 +20,13 @@
package org.eehouse.android.xw4;
+
+import android.app.ProgressDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
@@ -65,28 +69,107 @@ public class DictBrowseActivity extends XWListActivity
private int m_minAvail;
private int m_maxAvail;
private int[] m_counts;
+ private DictLoader m_loader;
+ private int m_nWords;
+ private class DictLoader extends AsyncTask
+ implements DialogInterface.OnCancelListener
+ {
+ private int m_closureTask;
+ private Intent m_intent;
+ private ProgressDialog m_progress;
-// - Steps to reproduce the problem:
-// Create ListView, set custom adapter which implements ListAdapter and
-// SectionIndexer but do not extends BaseAdapter. Enable fast scroll in
-// layout. This will effect in ClassCastException.
+ public DictLoader( Intent intent )
+ {
+ super();
+ m_intent = intent;
+ String msg = Utils.format( DictBrowseActivity.this,
+ R.string.scanning_dictf, m_name );
+ m_progress = ProgressDialog.show( DictBrowseActivity.this,
+ msg, null, true, true, this );
+ }
+
+ protected Void doInBackground( Void... nothing )
+ {
+ int closure = m_dictClosure;
+ DbgUtils.logf( "doInBackground" );
+ if ( null == m_counts ) {
+ m_counts = XwJNI.dict_iter_getCounts( closure );
+ }
+
+ DbgUtils.logf( "doInBackground: getCounts done" );
+
+ while ( null != m_counts && !isCancelled() ) { // while to break
+ figureMinMax();
+
+ DbgUtils.logf( "doInBackground: figureMinMax done" );
+
+ m_minShown = m_intent.getIntExtra( DICT_MIN, m_minAvail );
+ m_maxShown = m_intent.getIntExtra( DICT_MAX, m_maxAvail );
+
+ if ( isCancelled() ) {
+ break;
+ }
+
+ DbgUtils.logf( "doInBackground: calling wordCount" );
+ XwJNI.dict_iter_setMinMax( closure, m_minShown, m_maxShown );
+ m_nWords = XwJNI.dict_iter_wordCount( closure );
+ DbgUtils.logf( "doInBackground: wordCount done" );
+ break;
+ }
+
+ if ( isCancelled() ) {
+ synchronized( DictBrowseActivity.this ) {
+ Assert.assertTrue( 0 == m_dictClosure );
+ XwJNI.dict_iter_backDestroy( closure );
+ }
+ }
+
+ DbgUtils.logf( "doInBackground done" );
+ return null;
+ }
+
+ // Run on UI thread
+ @Override
+ protected void onCancelled()
+ {
+ DbgUtils.logf( "onCancelled called" );
+
+ m_dictClosure = 0;
+
+ finish();
+ }
+
+ // Run on UI thread
+ @Override
+ protected void onPostExecute( Void result )
+ {
+ DbgUtils.logf( "onPostExecute called" );
+ m_progress.cancel();
+ finishCreate();
+ }
+
+ //////////////////////////////////////////////////
+ // DialogInterface.OnCancelListener
+ //////////////////////////////////////////////////
+ public void onCancel( DialogInterface dialog )
+ {
+ DbgUtils.logf( "DictLoader.onCancel()" );
+ cancel( true );
+ }
+ }
private class DictListAdapter extends BaseAdapter
implements SectionIndexer {
private String[] m_prefixes;
private int[] m_indices;
- private int m_nWords;
public DictListAdapter()
{
super();
- XwJNI.dict_iter_setMinMax( m_dictClosure, m_minShown, m_maxShown );
- m_nWords = XwJNI.dict_iter_wordCount( m_dictClosure );
-
int format = m_minShown == m_maxShown ?
R.string.dict_browse_title1f : R.string.dict_browse_titlef;
setTitle( Utils.format( DictBrowseActivity.this, format,
@@ -155,6 +238,7 @@ public class DictBrowseActivity extends XWListActivity
} else {
m_name = name;
m_lang = DictLangCache.getDictLangCode( this, name );
+ m_counts = intent.getIntArrayExtra( DICT_COUNTS );
String[] names = { name };
DictUtils.DictPairs pairs = DictUtils.openDicts( this, names );
@@ -162,46 +246,17 @@ public class DictBrowseActivity extends XWListActivity
pairs.m_paths[0],
JNIUtilsImpl.get() );
- m_counts = intent.getIntArrayExtra( DICT_COUNTS );
- if ( null == m_counts ) {
- m_counts = XwJNI.dict_iter_getCounts( m_dictClosure );
- }
- if ( null == m_counts ) {
- // empty dict? Just close down for now. Later if
- // this is extended to include tile info -- it should
- // be -- then use an empty list elem and disable
- // search/minmax stuff.
- String msg = Utils.format( this, R.string.alert_empty_dictf,
- name );
- showOKOnlyDialogThen( msg, FINISH_ACTION );
- } else {
- figureMinMax();
-
- setContentView( R.layout.dict_browser );
-
- Button button = (Button)findViewById( R.id.search_button );
- button.setOnClickListener( new View.OnClickListener() {
- public void onClick( View view )
- {
- findButtonClicked();
- }
- } );
-
- m_minShown = intent.getIntExtra( DICT_MIN, m_minAvail );
- m_maxShown = intent.getIntExtra( DICT_MAX, m_maxAvail );
- setUpSpinners();
-
- setListAdapter( new DictListAdapter() );
- getListView().setFastScrollEnabled( true );
- }
+ m_loader = new DictLoader( intent );
+ DbgUtils.logf( "calling DictLoader.execute()" );
+ m_loader.execute();
}
+ DbgUtils.logf( "onCreate() done" );
}
@Override
protected void onDestroy()
{
- XwJNI.dict_iter_destroy( m_dictClosure );
- m_dictClosure = 0;
+ destroyDict();
super.onDestroy();
}
@@ -210,7 +265,7 @@ public class DictBrowseActivity extends XWListActivity
@Override
public void finalize()
{
- XwJNI.dict_iter_destroy( m_dictClosure );
+ destroyDict();
try {
super.finalize();
} catch ( java.lang.Throwable err ){
@@ -342,6 +397,45 @@ public class DictBrowseActivity extends XWListActivity
m_maxSpinner.setOnItemSelectedListener( this );
}
+ private void finishCreate()
+ {
+ if ( null == m_counts ) {
+ // empty dict? Just close down for now. Later if
+ // this is extended to include tile info -- it should
+ // be -- then use an empty list elem and disable
+ // search/minmax stuff.
+ String msg = Utils.format( this, R.string.alert_empty_dictf,
+ m_name );
+ showOKOnlyDialogThen( msg, FINISH_ACTION );
+ } else {
+ // figureMinMax();
+
+ setContentView( R.layout.dict_browser );
+
+ Button button = (Button)findViewById( R.id.search_button );
+ button.setOnClickListener( new View.OnClickListener() {
+ public void onClick( View view )
+ {
+ findButtonClicked();
+ }
+ } );
+
+ setUpSpinners();
+
+ setListAdapter( new DictListAdapter() );
+ getListView().setFastScrollEnabled( true );
+ }
+ }
+
+ private void destroyDict()
+ {
+ synchronized( this ) {
+ if ( 0 != m_dictClosure ) {
+ XwJNI.dict_iter_destroy( m_dictClosure );
+ m_dictClosure = 0;
+ }
+ }
+ }
public static void launch( Context caller, String name )
{