开发者

Android: Problems with ProgressDialog

Dear Android hackers, I am trying to do the following in my Android App: When the User clicks on a list item in a ListActivity, a ProgressDialog should show up, some preloading should happen and after it's done, another Activity should be called using an intent.

I tried different approaches. What didn't work at all was using an Async Task. Apparently I cannot show, dismiss or edit my ProgressDialog out of the Async Task, if that Class is not a Member of my original Activity.

I switched to a simple Thread then, this is how I'm trying to do it:

dialog = ProgressDialog.show(BookmarkActivity.this, "", "Loading...",true);
new Thread() {
    public void run() {
        // do something
        dialog.setMessage("Change Message...");
        // do more
        dialog.dismiss();
        // ...
        Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class);
        BookmarkActivity.this.startActivity(intent);
    }
}.start();

This works almost, but the changing of the dialog message does not. I'm getting errors saying something about "leaked windows". (I can post the complete log if it is needed).

My questions:

  • How can I use an Async Task for this, where the Class has it's own file?
  • How can I change the ProgressDialog out of my Thread or AsyncTask without causing an error for changing the UI in another thread?

Thanks in advance, Jan Oliver


Ok, with the help of Jason, I put together this Async Task. That works!

public class ThreadPreLoader extends AsyncTask<Object, String, Void> {

    private Activity mActivity;
    private ProgressDialog mDialog;

    public ThreadPreLoader(Activity activity) {
        mActivity = activity;
    }

    protected void onPreExecute() {
        mDialog = new ProgressDialog(mActivity);
        mDialog.setMessage("Loading...");
        mDialog.show();
    }

    protected Void doInBackground(Object... args) {
        publishProgress("Loading something else..");
        return null;
    }

    protected void onProgressUpdate(String... msg) {
        mDialog.setMessage(msg[0]);
    }

    protected void onPostExecute(Void result) {
        mDialog.dismiss();
    }
}

Thanks ag开发者_JAVA技巧ain, Jason.


You should use an Async Task, Define a custom Async Task which receives the context (this) of the original activity. Then keep that context for later Dismissing the dialog. From your doInBackground() method you can call postProgress( int progress) which will cause onProgressUpdate() to be called in the async task , this method is on the UI thread so it will not cause cross thread errors. Once doInBackground() is complete the method onComplete() will also be called on the UI thread, this is where you can use your saved context and dissmiss the dialog (context.dissmissDialog()


Take a look at Android's Handler class. If you create the Handler in the onCreate method of your activity, Runnables that are sent to the post method of the handler are then run on the UI thread of your activity:

Handler h;
protected void onCreate(Bundle bundle) {
   h = new Handler;

   new Thread() {
     public void run() {
        // your run code

        h.post(new Runnable() { /* change dialog here */ });
     }
   }.start();

}

I'm not sure that's the best option, but worth a try.


In AsyncTask
You should do you work which need time in doInBackground and calling intent like things, that you need to do after this task should be in onPostExecute

public class ThreadPreLoader extends AsyncTask<Object, String, Void> {

    private Activity mActivity;
    private ProgressDialog mDialog;

    public ThreadPreLoader(Activity activity) {
        mActivity = activity;
    }

    protected void onPreExecute() {
        mDialog = new ProgressDialog(mActivity);
        mDialog.setMessage("Loading...");
        mDialog.show();
    }

    protected Void doInBackground(Object... args) {
         //do more
        publishProgress("Loading something and reached somewhere..");
         //do more
        publishProgress("Loading something and reached somewhere..");
         //do more
        return null;
    }

    protected void onProgressUpdate(String msg) {
        mDialog.setMessage(msg);
    }

    protected void onPostExecute() {
        Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class);
    BookmarkActivity.this.startActivity(intent);

        mDialog.dismiss();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜