From 6f76d99986482fd43ab6a47c9a9409c0427d2529 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Sat, 10 Dec 2011 08:47:09 -0800 Subject: [PATCH] first cut at opening dict in a cancellable task with indeterminate progress dialog. Doesn't look promising: time to open dict increases three or four fold. Unless I can address that this will be abandoned as slow opens are only a problem with pathologically large dicts like Polish. Still to try: replace indeterminate progress, which needs periodic redraws, with static text. --- .../android/XWords4/res/values/strings.xml | 2 + .../android/xw4/DictBrowseActivity.java | 180 +++++++++++++----- 2 files changed, 139 insertions(+), 43 deletions(-) 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 ) {