Here's a quick attempt at rewriting it without a static. Turned out
more complex than I'd like. Pastebin version:
http://pastebin.com/m7b8b184
Inline version:
public class MyActivity extends Activity {
private final static String LOG_TAG = MyActivity.class.getSimpleName
();
private final static int DIALOG_ID = 1;
private Task mTask;
private boolean mShownDialog;
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if ( id == DIALOG_ID ) {
mShownDialog = true;
}
}
private void onTaskCompleted() {
Log.i(LOG_TAG, "Activity " + this + " has been notified the
task is
complete.");
//Check added because dismissDialog throws an exception if the
current
//activity hasn't shown it. This Happens if task finishes early
enough
//before an orientation change that the dialog is already gone
when
//the previous activity bundles up the dialogs to reshow.
if ( mShownDialog ) {
dismissDialog(DIALOG_ID);
Toast.makeText(this, "Finished..",
Toast.LENGTH_LONG).show();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Object retained = getLastNonConfigurationInstance();
if ( retained instanceof Task ) {
Log.i(LOG_TAG, "Reclaiming previous background task.");
mTask = (Task) retained;
mTask.setActivity(this);
} else {
Log.i(LOG_TAG, "Creating new background task.");
mTask = new Task(this);
mTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
mTask.setActivity(null);
return mTask;
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_ID:
ProgressDialog dialog = new
ProgressDialog(this);
dialog.setMessage("Loading stuff..");
dialog.setCancelable(true);
return dialog;
}
return super.onCreateDialog(id);
}
private static class Task extends AsyncTask<Void, Void, Void> {
private MyActivity activity;
private boolean completed;
private Task(MyActivity activity) {
this.activity = activity;
}
@Override
protected void onPreExecute() {
activity.showDialog(DIALOG_ID);
}
@Override
protected Void doInBackground(Void... unused) {
try {
Log.i(LOG_TAG, "Background thread starting
sleep.");
Thread.sleep(15 * 1000);
} catch (InterruptedException e) {
Log.e(LOG_TAG, "Thread interrupted:", e);
}
Log.i(LOG_TAG, "Background thread finished sleep.");
return null;
}
@Override
protected void onPostExecute(Void unused) {
completed = true;
notifyActivityTaskCompleted();
}
private void notifyActivityTaskCompleted() {
if ( null != activity ) {
activity.onTaskCompleted();
}
}
private void setActivity(MyActivity activity) {
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
On Nov 10, 5:41 pm, Lee Jarvis <[email protected]> wrote:
> I've tried that, too. But again to no avail, nothing I do seems to
> work. I've tried using the callback features whilst also implementing
> weak references which also doesn't work. Once I change orientation,
> the progressDialog never disappears, it's bugging me to hell
>
> On 8 Nov, 17:41, Streets Of Boston <[email protected]> wrote:
>
> > If you do showDialog(dialogId) and dismissDialog(dailogId), Android
> > actively manages the showing and hiding of the dialog on configuration
> > changes.
>
> > E.g. if you called showDialog(id) and your rotate your screen, Android
> > will make sure that the dialog is shown again when the activity is
> > recreated for the new configuration. To dismiss it, you have to
> > explicitly call dismissDialog(id).
>
> > However, you must call 'dismissDialog' on the currently active
> > activity. That's where the trick with 'ACTIVE_INSTANCE' comes in:
> > ACTIVE_INSTANCE.showDialog(ACTIVE_TASKING) and
> > ACTIVE_INSTANCE.dismissDialog(DIALOG_TASKING).
>
> > On Nov 8, 4:28 am,LeeJarvis<[email protected]> wrote:
>
> > > Well, that's the thing. It's not a progress 'bar' that I can just show/
> > > hide which would seem a lot easier. I'm just using a ProgressDialog
> > > that I dismiss in onPostExecute, The code you see above inside of my
> > > AsyncTask is what I'm using to show/hide the dialog. I use showDialog
> > > () in onPreExecute and dismissDialog() in onPostExecute, I realize one
> > > a new activity is created and the old one is killed it'll lose
> > > reference to that dialog so I'm guessing that's why dismissDialog()
> > > doesn't work (on in fact the code in onPostExecute() doesn't get
> > > executed because the phone has change orientation and it's trying to
> > > dismiss a dialog which doesn't exist.
>
> > > On 8 Nov, 03:52, Streets Of Boston <[email protected]> wrote:
>
> > > > Show us your code that deals with showing/hiding the progress bar and
> > > > show exactly what doesn't work.
> > > > Maybe we can figure it out :)
>
> > > > On Nov 7, 5:32 pm,LeeJarvis<[email protected]> wrote:
>
> > > > > Any other suggestions? I keep trying different things out but nothing
> > > > > seems to work, I keep seeing common applications with the same
> > > > > functionality which is making it more frustrating because I know it
> > > > > should work fine
>
> > > > > On 7 Nov, 17:29,LeeJarvis<[email protected]> wrote:
>
> > > > > > Thanks for your reply, it's made me understand things a little
> > > > > > better.
>
> > > > > > Unfortunately that still doesn't seem to work..
>
> > > > > > The Toast popup appears twice, then the ProgressDialog just
> > > > > > continues
> > > > > > to run regardless
>
> > > > > > On Nov 7, 5:14 pm, Streets Of Boston <[email protected]>
> > > > > > wrote:
>
> > > > > > > Lance is absolutely right. I ran into this problem a few months
> > > > > > > ago.
>
> > > > > > > Possible solution:
> > > > > > > Hold a static handle to your currently active instance of your
> > > > > > > activity (works only if you have at most one active instance of
> > > > > > > your
> > > > > > > activity at any given time in your process).
>
> > > > > > > public class MyActivity extends Activity {
> > > > > > > public static final MyActivity ACTIVE_INSTANCE;
> > > > > > > private final static int DIALOG_TASKING = 1;
>
> > > > > > > ProgressDialog mLoadingDialog;
>
> > > > > > > @Override
> > > > > > > public void onCreate(Bundle savedInstanceState) {
>
> > > > > > > ACTIVE_INSTANCE = this;
>
> > > > > > > super.onCreate(savedInstanceState);
> > > > > > > setContentView(R.layout.main);
>
> > > > > > > new Task().execute();
> > > > > > > }
>
> > > > > > > @Override
> > > > > > > public void onDestroy() {
> > > > > > > super.onDestroy();
>
> > > > > > > ACTIVE_INSTANCE = null;
> > > > > > > }
>
> > > > > > > @Override
> > > > > > > protected Dialog onCreateDialog(int id) {
> > > > > > > switch (id) {
> > > > > > > case DIALOG_TASKING:
> > > > > > > mLoadingDialog = new ProgressDialog(this);
> > > > > > > mLoadingDialog.setMessage("Loading stuff..");
> > > > > > > mLoadingDialog.setCancelable(true);
> > > > > > > return mLoadingDialog;
> > > > > > > }
> > > > > > > return super.onCreateDialog(id);
> > > > > > > }
>
> > > > > > > private static class Task extends AsyncTask<Void, Void, Void>
> > > > > > > {
>
> > > > > > > protected void onPreExecute() {
> > > > > > > ACTIVE_INSTANCE.showDialog(DIALOG_TASKING);
> > > > > > > }
>
> > > > > > > protected Void doInBackground(Void... unused) {
> > > > > > > for (int i = 0; i < 4000000; i++) { }; //
> > > > > > > just
> > > > > > > to take some time up
> > > > > > > return null;
> > > > > > > }
>
> > > > > > > protected void onPostExecute(Void unused) {
> > > > > > > ACTIVE_INSTANCE.dismissDialog
> > > > > > > (DIALOG_TASKING);
> > > > > > > Toast.makeText(ACTIVE_INSTANCE,
> > > > > > > "Finished..",
> > > > > > > Toast.LENGTH_LONG).show();
> > > > > > > }
> > > > > > > }
>
> > > > > > > }
>
> > > > > > > You may need to put null checks in your code before using
> > > > > > > ACTIVE_INSTANCE.
> > > > > > > But, you get the idea :)
>
> > > > > > > On Nov 7, 11:45 am,LeeJarvis<[email protected]> wrote:
>
> > > > > > > > Ah ok, that makes sense. Thanks for your reply. I understand
> > > > > > > > what
> > > > > > > > you're saying, but in all honesty after trying another 3
> > > > > > > > examples I'm
> > > > > > > > still unable to resolve this, could you possibly provide some
> > > > > > > > kind of
> > > > > > > > example for what would work?
>
> > > > > > > > Seems if I use a reference to a ProgressDialog in my activity
> > > > > > > > it'll
> > > > > > > > leak, and if I use the showDialog() methods it'll continue
> > > > > > > > forever.
>
> > > > > > > > Thanks
>
> > > > > > > > On Nov 7, 4:39 pm, Lance Nanek <[email protected]> wrote:
>
> > > > > > > > > >private final class Task extends AsyncTask<Void, Void, Void>
> > > > > > > > > >{
> > > > > > > > > ...
> > > > > > > > > >dismissDialog(DIALOG_TASKING);
>
> > > > > > > > > A non-static inner class like this has a reference to the
> > > > > > > > > instance of
> > > > > > > > > the class that created it. So that dismissDialog call
> > > > > > > > > probably goes to
> > > > > > > > > the previous instance of your activity in this case. Not the
> > > > > > > > > current
> > > > > > > > > one if there has been an orientation change and the activity
> > > > > > > > > has been
> > > > > > > > > recreated.
>
> > > > > > > > > >public void onDestroy() {
> > > > > > > > > >dismissDialog(DIALOG_TASKING);
>
> > > > > > > > > This is called too late to matter. Dialogs created by
> > > > > > > > > showDialog are
> > > > > > > > > managed by the Activity class. It records which dialogs have
> > > > > > > > > to be
> > > > > > > > > reshown when the activity is recreated due to an orientation
> > > > > > > > > change.
> > > > > > > > > It does so right after the call to onSaveInstanceState. That
> > > > > > > > > happens
> > > > > > > > > before onDestroy.
>
> > > > > > > > > On Nov 7, 9:53 am,LeeJarvis<[email protected]> wrote:
>
> > > > > > > > > > I apologise if I'm missing something or just being stupid..
> > > > > > > > > > But i've
> > > > > > > > > > tried the following..
>
> > > > > > > > > > @Override
> > > > > > > > > > public void onDestroy() {
> > > > > > > > > > dismissDialog(DIALOG_TASKING);
> > > > > > > > > > super.onDestroy();
> > > > > > > > > > }
>
> > > > > > > > > > The dialog is only dismissed if I DONT change orientation,
> > > > > > > > > > otherwise
> > > > > > > > > > the "finished" toast will show, but the ProgressDialog will
> > > > > > > > > > never
> > > > > > > > > > actually disappear.
>
> > > > > > > > > > On Nov 7, 2:41 pm, Mark Murphy <[email protected]>
> > > > > > > > > > wrote:
>
> > > > > > > > > > >LeeJarviswrote:
> > > > > > > > > > > > This code (kinda) works, the only problem is dismissing
> > > > > > > > > > > > the dialog if
> > > > > > > > > > > > the activity is recreated. I've tried dismissing it if
> > > > > > > > > > > > mTaskComplete
> > > > > > > > > > > > is true but I guess by that time it's lost reference to
> > > > > > > > > > > > the
> > > > > > > > > > > > ProgressDialog.
>
> > > > > > > > > > > You may need to dismiss the dialog in onDestroy() and
> > > > > > > > > > > reopen it in
> > > > > > > > > > > onCreate(), if the flag is true.
>
> > > > > > > > > > > --
> > > > > > > > > > > Mark Murphy (a Commons
> > > > > > > > > > > Guy)http://commonsware.com|http://twitter.com/commonsguy
>
> > > > > > > > > > > Android App Developer
> > > > > > > > > > > Books:http://commonsware.com/books-Hidequotedtext-
>
> > > > > > > > - Show quoted text -- Hide quoted text -
>
> > > > > - Show quoted text -- Hide quoted text -
>
> > > - Show quoted text -
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en