Note that there are some explanatory texts on larger screens.

plurals
  1. POcanceling an AsyncTask which uses a ProgressDialog
    primarykey
    data
    text
    <p>I have an AsyncTask which launches a DatabaseHelper class from DoinBackground which copies an SQLite database from the /assets directory to the application directory (/databases). </p> <p>In preExecute(), I startup a progressDialog. As pieces of the DB helper class complete, the DoinBackground process updates the progressDialog.</p> <p>When the device is rotated, as I understand it, I need to dismiss the dialog box, cancel the AsyncTask, and then restart both again in onResume(), after the rotation is finished.</p> <p>The first problem is when I call AsyncTask.cancel(), my onCancel() event fires, but the AsyncTask keeps running. I know because LogCat is showing output from my DB Helper long after the rotation is finished. The UI is usable after the rotation because the progressDialog is gone but the DB still appears to be mucking around copying so this is no good.</p> <p>One piece of info I googled said you can't cancel an AsyncTask, so do I just let the thing run in the background on not worry about it? Is there a way to hook up the (still executing) DoinBackground process to the progressDialog again? </p> <p>Thanks</p> <pre><code> package com.test.helloasync; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.util.Log; public class HelloAsync extends Activity { myVars v; protected fileCopyTask fct; private final String TAG = "** HelloAsync **"; private final String DBNAME = "foo.png"; // need png extension: Data exceeds UNCOMPRESS_DATA_MAX (5242880 vs 1048576) @Override public void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.main); restoreFromObject (); } /* (non-Javadoc) * @see android.app.Activity#onResume() */ @Override protected void onResume () { // TODO Auto-generated method stub Log.d (TAG, "onResume()"); // only start NEW task if not cancelled and file has not been copied yet if ((v.taskCancelled == false) &amp;&amp; (v.fileCopied == false)) { fct = new fileCopyTask (); fct.execute (); } // show progressdialog if we were cancelled becuase asynctask will continue by itself if ((v.taskCancelled == true) &amp;&amp; (v.fileCopied == false)) { Log.d (TAG, "onAttachedToWindow(): launching fct"); v.pd.show (); // may need to check status here to make sure it was cancelled and not something else... Log.d (TAG, "fct cancel status is " + fct.isCancelled ()); } super.onResume (); } /** * saves myVars class during rotation */ @Override public Object onRetainNonConfigurationInstance () { Log.d (TAG, "onRetainNonConfigurationInstance(): saving myVars objects"); // close db transfer dialogs if showing so we don't cause a UI error if (v.pd != null) if (v.pd.isShowing ()) { v.taskCancelled = true; v.pd.cancel (); } // save task to myVars so we can use it onRestoreInstanceState v.fct = fct; return (v); } /* * restores myVars class after rotation */ private void restoreFromObject () { Log.d (TAG, "restoreFromObject(): retrieving myVars object"); v = (myVars) getLastNonConfigurationInstance (); // initialize myVars object (v) first time program starts if (v == null) v = new myVars (); else { Log.d (TAG, "myVars already initialized"); fct = (fileCopyTask) v.fct; } } /** * * copy a file from /assets to /data/data/com.blah.blah/databases * */ private class fileCopyTask extends AsyncTask&lt;Integer, Void, Void&gt; { // on UI thread here protected void onPreExecute () { Log.d (TAG, "onPreExecute()" ); // only show this when db has not been copied // set initDbDone to false prir to call if downloading a new DB v.pd = new ProgressDialog (HelloAsync.this); v.pd.setProgressStyle (ProgressDialog.STYLE_HORIZONTAL); v.pd.setMessage ("Initializing Database"); v.pd.show (); } /** * opens file in assets/ directory and counts the bytes in it so we can have an actual progress bar * * @return size */ private int getAssetSize () { int size = 0; try { InputStream fin = getBaseContext ().getAssets ().open (DBNAME); byte [] buffer = new byte [1024]; int length = 0; while ((length = fin.read (buffer)) &gt; 0) size += length; fin.close (); } catch (IOException ioe) { Log.d (TAG, "fileCopyTask(): asset size failed: ioex :" + ioe); size = 0; } Log.d (TAG, " fileCopyTask(): asset size is " + size); return (size); } @Override protected Void doInBackground (Integer... params) { Log.d (TAG, "doInBackground: +++++++++++++++++++++++++++++++++"); try { int inputsize = getAssetSize (); // this is the input file in the assets directory. We have no idea how big it is. InputStream fin = getBaseContext ().getAssets ().open (DBNAME); // this is the destination database file on the android device File dbFile = getBaseContext ().getDatabasePath (DBNAME); // check if destination directory exists String parent = dbFile.getParent (); // create the desitination directory if it does not exist in /data/data/blah.. (on device) if (dbFile.exists () == false) { boolean result = new File (parent).mkdir (); Log.d (TAG, " fileCopyTask(): mkdir() result is " + result); } // this is the output file in the databases/ subdirectory of the app directory (on device) OutputStream fout = new FileOutputStream (dbFile); // transfer bytes from the inputfile to the outputfile byte [] buffer = new byte [4096]; int length; int bytesCopied = 0; while ((length = fin.read (buffer)) &gt; 0) { fout.write (buffer, 0, length); bytesCopied += length; float b = (float) (bytesCopied * 1.0); float i = (float) (inputsize * 1.0); float pctdone = (float) ((b / i) * 100.0); int pct = (int) (pctdone); // updating every 4k seems to really slow things down so do it every 5 chunks if ((pct % 5) == 0) v.pd.setProgress ((int) pctdone); } fout.flush (); fin.close (); fout.close (); } catch (IOException e) { Log.d (TAG, "fileCopyTask(): DB copy blew up. IOE: " + e.getMessage ()); // just in case, attempt to cancel the process in event of cataclysm this.cancel (true); e.printStackTrace (); } return null; } // can use UI thread here protected void onPostExecute (final Void unused) { Log.d (TAG, "fileCopyTask():onPostExecute()"); // set progress bar to 100% when done. v.pd.setProgress (100); v.pd.dismiss (); // set the state flags to show a succesful completion v.taskCancelled = false; v.fileCopied = true; }// onPostExecute() }// fileCopyTask() } /////////////////////////////////////// // myVars.java ////////////////////////////////////// /** * */ package com.test.helloasync; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.content.DialogInterface; public class myVars { ProgressDialog pd; boolean taskCancelled = false; boolean fileCopied = false; Object fct; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload