1

I looked at a few other questions regarding a similar issue, and I figured out that I need to use the onProgressUpdate method to change the message of ProgressDialog.

For example, I have code like this that runs in the AsyncTask's doInBackGround (this is just a very small sample):

        byte[] data = getBytesFromFile(image);

        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        pictures.dia.setProgress(30);
        pictures.dia.setMessage("Data beginning upload sequence...");

        URL connectURL = new URL(this.base_url);
        HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");

        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Content-Type", "multipart/form-data, boundary=" + boundary);

        DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
        pictures.dia.setProgress(40);
        pictures.dia.setMessage("Output Stream prepared...");

When I originally run thus, I get a Leaky Window error saying that I can't change dia's message outside of AsyncTask.

So my question is, how do I use onProgressUpdate to set the message of dia when dia's progress reaches a certain number? (i.e., when dia's progress = 30, make it say "Data beginning upload sequence...")
onProgressUpdate must obviously always be checking dia's progress (like a listener, I suppose)[if it doesn't already do this, how can I make it do this?]

Mxyk
  • 10,678
  • 16
  • 57
  • 76

2 Answers2

5

You need to implement the onProgressUpdate method of AsyncTask. Create a new class that holds the progress percentage and the message only to be the onProgressUpdate method's only parameter.

In the onProgressUpdate, call dia.setProgress and dia.setMessage.

In your doInBackground method, call publishProgress with an instance of your new class that contains the new percentage and message. That will cause the AsyncTask to call onProgressUpdate on the main thread.

For example:

private static class TaskProgress {
    final int percentage;
    final String message;

    TaskProgress(int percentage, String message) {
        this.percentage = percentage;
        this.message = message;
    }
}

In your AsyncTask (replace the ?s with the correct types for your implementation):

public ProgressAsyncTask extends AsyncTask<?, TaskProgress, ?> {

    public void onProgressUpdate(TaskProgress progress) {
         pictures.dia.setProgress(progress.percentage);
         pictures.dia.setMessage(progress.message);
    }

    public ? doInBackground(?... params) {
        // ... your code       
        publishProgress(new TaskProgress(30, "A new update"));
        // ... your code 
    }

}
poke
  • 369,085
  • 72
  • 557
  • 602
Brigham
  • 14,395
  • 3
  • 38
  • 48
  • Okay, I see how this works. I have one problem right now: I'm getting an error when I put `publishProgress(new TaskProgress(10, "Beginning sequence..."));` in some `runnable` code. My runnable is called in the `doInBackground` method, but isn't physically in that method. Also, the runnable later calls another method from another class, where I can't use `publishProgress`. Any way around this? – Mxyk Nov 01 '11 at 17:42
  • Note: if I try `Task.publishProgress(new TaskProgress(10, "My message here..."));`, it says that publishProgress is not visible from the AsyncTask. Not sure if that helps or not. – Mxyk Nov 01 '11 at 17:45
  • You have to call publishProgress inside your doInBackground method. – Brigham Nov 01 '11 at 18:42
  • Thats not the problem. All my doInBackground method is is `uploader.run()`, where I run my Runnable code that is **outside** the `doInBackground` method. Do you see the problem here? `doInBackground` calls the runnable and nothing more, and I don't want to put the runnable inside `doInBackground`. – Mxyk Nov 02 '11 at 16:29
1

You're right in that you should put the code for updating the views in dia in the onProgressUpdate method. To ensure that onProgressUpdate is called, though, you need to make calls to publishProgress. Basically, you call publishProgress from your background thread and then the system, at some undefined time in the future, will invoke onProgressUpdate on the UI thread.

Chris
  • 22,923
  • 4
  • 56
  • 50
  • So instead of `pictures.dia.setProgress(some number)`, I should use `publishProgress(some number)`? OK, from there though, how does `onProgressUpdate` display the right message I want? – Mxyk Nov 01 '11 at 17:30