2

Here is my AsyncTask class:

    private class Task extends AsyncTask<Void, Integer, Void> {

        @Override protected void onPreExecute() {
            dia = new ProgressDialog(pictures.this);
            dia.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dia.setMessage("Please wait while content is loaded...");
            dia.setCancelable(false);
            dia.show();
        }

        @Override protected Void doInBackground(Void... voids) {


            Thread thread = new Thread(null, uploader, "MagentoBackground");
            thread.start();

            //publishProgress(100);  keep this commented or no?
            return null;
        }

        @Override public void onProgressUpdate(Integer... prog) {
            if (prog == null)
                return;
            dia.setProgress(prog[0]);
        }

        @Override  protected void onPostExecute(Void voids) {
            dia.setMessage("Done");
            dia.cancel();
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }

There is one major and one minor problem I am concerned with right now. Here are the major and minor problems, consecutively:

  • This app's intention is to take a picture and upload it to a website. As soon as the user hits the 'OK' button to upload, the AsyncTask dialog shows, so this is fine. However, it only shows the dialog box for a split second, already 100% completed, and then force closes. However, it is most certainly not 100% complete! When I look at the website and refresh the page, it doesn't show the picture. (On WiFi, the picture actually does upload near immediately, and when the website is refreshed right away, it shows the new picture. But on 3G, this process can take minutes - which is why I want the user to see the progress of the photo being uploaded).

  • I'm not sure how to use the onProgressUpdate. I've tried several tutorials, to no avail. If anyone can state what I can do for this situation, it will be helpful

Edit:

Runnable code:

private Runnable uploader = new Runnable() {
        @Override
        public void run() {

            /**JER 3**/
            if (teacherInfo != null)
                teacher = " - " + teacherInfo ;
            else teacher = "" ;

            if (schoolInfo != null )
                school = " - " + schoolInfo ;
            else school = "" ;


            /********/

            if(Descriptor.desString.equals("")) Descriptor.desString = "No description provided.";

            int sessionId = rapi.createSession(experimentInput.getText().toString(), 
                    name.getText().toString() + teacher + school + " - " + time, 
                    Descriptor.desString, "n/a", "Lowell, MA", "");


            JSONArray dataJSON = new JSONArray();
            JSONArray subData = new JSONArray();

                try {
                    subData.put(curTime); subData.put(Lat); subData.put(Long); subData.put(Descriptor.desString);
                    dataJSON.put(subData);
                }
                catch (JSONException e) {
                    e.printStackTrace();
                }


            Boolean result = rapi.updateSessionData(sessionId, experimentInput.getText().toString(), dataJSON);

            if (result) {
                rapi.uploadPictureToSession(picture, experimentInput.getText().toString(), 
                        sessionId, name.getText().toString() + teacher + school + " - " + time, 
                        name.getText().toString() + Descriptor.desString);
            }

            //if (m_ProgressDialog != null && m_ProgressDialog.isShowing()) m_ProgressDialog.dismiss();
        }
    };
Mxyk
  • 10,678
  • 16
  • 57
  • 76
  • As the issue is in the Force Close, could we take a look at the logcat? Also: you should not start a new Thread in doInBackground since it is run in another thread already – Laurent' Oct 24 '11 at 16:45
  • Well, it doesn't force close. The app continues like it normally does, allowing you to name a new experiment and take more pictures. Its just that the `ProgressDialog` is dismissing before the picture gets uploaded. – Mxyk Oct 24 '11 at 16:46

1 Answers1

4

You are starting a new thread inside an already seperated thread.

doInBackground() gets executed in a different thread then the UI-methods onPreExecute(), onPostExecute() and onProgressUpdate() of the AsyncTask class. All that your async task does here is start a third thread. This takes almost no time. After that your task is finished, resulting in the dialog closing immediately.

You can do your uploading inside doInBackground(), you don't need to start a new thread there. That's what the AsyncTask class does for you already.

Regarding progress: onProgressUpdate() gets called every time you execute publishProgress(). So this is correctly implemented, you just have to call publishProgress() multiple times during the upload process to update the progressbar accordingly (e.g. every percent sent).

  • That makes sense. Now the problem is that the actual picture uploading process, placed in a `Runnable`, won't upload the picture when it's placed in the `AsyncTask`'s `doInBackground`. Once again, the dialog showed quickly then closed, only now nothing is being uploaded. I will paste my `Runnable` code into the question. – Mxyk Oct 24 '11 at 16:57
  • I'm no expert when it comes to Java and it's multithreading framework, but chances are that you are executing your code in yet another thread, depending on how you start your `Runnable`. From the looks of it, you can fix this by putting the code from the `Runnables.run()` method into `doInBackground()`. –  Oct 24 '11 at 17:30
  • Yup, that covers it the uploading! How should I exactly use `onProgressUpdate()` though? I'm still confused. – Mxyk Oct 24 '11 at 18:13
  • The deal with `onProgressUpdate()` is that you don't call it directly. All you do with it is implementing what should happen after the progress changed (in this case update a progress bar). To actually update the progress, call `publishProgress()` with a value that indicates the progress. I'd say a value between 0 and 100 for a % sent is ok here *(make sure that your progress bar has it's min and max. values set to 0 and 100 in this case, otherwise your bar might stop in a different position)*. ... –  Oct 24 '11 at 18:31
  • 1
    ... Thats the general approach. The problem in this situation is that you need some callback that tells you how much you have uploaded yet. This is a bit tricky on android due to some bugs and requires some work to implement. See [this question](http://stackoverflow.com/questions/3213899/cant-grab-progress-on-http-post-file-upload-android) for an example and more info. –  Oct 24 '11 at 18:31
  • I see.. Well then, I won't be bothered to implement that. Thank you for your help! – Mxyk Oct 25 '11 at 17:31