ProgressDialog in AsyncTask which has a thread in

2019-08-09 08:28发布

问题:

I want to upload an image to my server. Therfore i've build this and sending to the server works quite well. Yet one thing is missing, which is ProgressDialog. I tried a lot of ways but don't know how to do it the right way. I call ImageUploader.uploadFile() in an AsyncTask in the preExecute method at the moment.

As within the doInBackground i have to send an E-mail which has the photo as attachment with it. So the photo needs to be uploaded before it's attached to the email. So how to do this and how to show the ProgressDialog?

This is how I Call the function:

       @Override
        protected void onPreExecute(){
            super.onPreExecute();
            if(isPhotoTaken()){
                ImageUploader.uploadFile(getPhotoPath(), "http://www.example.com/upload.php", Step4.this);              
            }
        }

This is my ImageUploader class

    public class ImageUploader {

    private static String serverResponseMessage = "";
    private static int serverResponseCode = 0;
    private static ProgressDialog dialog;

    public static int uploadFile(final String sourceFileUri, final String serverFile, final Context context) {

        Debug.out("SourceFileUri: " + sourceFileUri);
        Debug.out("ServerFile: " + serverFile);
        Thread thread = new Thread() {
            @Override
            public void run() {
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        dialog = new ProgressDialog(context);
                        dialog.setCancelable(false);
                        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                        dialog.setMessage("Uploading Image... Please wait!");
                        dialog.show();
                    }
                });
                String upLoadServerUri = serverFile;
                String fileName = sourceFileUri;
                HttpURLConnection conn = null;
                DataOutputStream dos = null;
                String lineEnd = "\r\n";
                String twoHyphens = "--";
                String boundary = "*****";
                int bytesRead, bytesAvailable, bufferSize;
                byte[] buffer;
                int maxBufferSize = 1 * 1024 * 1024;
                File sourceFile = new File(sourceFileUri);
                if (!sourceFile.isFile()) {
                    Log.e("uploadFile", "Source File Does not exist");
                }
                try { // open a URL connection to the Servlet
                    Debug.out("in the try");
                    FileInputStream fileInputStream = new FileInputStream(
                            sourceFile);
                    URL url = new URL(upLoadServerUri);
                    conn = (HttpURLConnection) url.openConnection(); // Open a
                                                                        // HTTP
                                                                        // connection
                                                                        // to
                                                                        // the
                                                                        // URL
                    conn.setDoInput(true); // Allow Inputs
                    conn.setDoOutput(true); // Allow Outputs
                    conn.setUseCaches(false); // Don't use a Cached Copy
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("Connection", "Keep-Alive");
                    conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                    conn.setRequestProperty("Content-Type",
                            "multipart/form-data;boundary=" + boundary);
                    conn.setRequestProperty("uploaded_file", fileName);
                    dos = new DataOutputStream(conn.getOutputStream());
                    Debug.out("Set Properties and Datastream");
                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                            + fileName + "\"" + lineEnd);
                    dos.writeBytes(lineEnd);
                    Debug.out("Writes data");
                    bytesAvailable = fileInputStream.available(); // create a
                                                                    // buffer of
                                                                    // maximum
                                                                    // size

                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];
                    Debug.out("Buffer done");
                    // read file and write it into form...
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    Debug.out("Read Bytes");
                    while (bytesRead > 0) {
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                    }

                    // send multipart form data necesssary after file data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                    Debug.out("After sendData");
                    // Responses from the server (code and message)
                    serverResponseCode = conn.getResponseCode();
                    serverResponseMessage = conn.getResponseMessage();
                    Debug.out("Server Response: " + serverResponseCode);
                    Log.i("uploadFile", "HTTP Response is : "
                            + serverResponseMessage + ": " + serverResponseCode);
                    Debug.out("HTTP Response is : " + serverResponseMessage
                            + ": " + serverResponseCode);
                    // close the streams //
                    fileInputStream.close();
                    dos.flush();
                    dos.close();
                }

                catch (MalformedURLException ex) {
                    ex.printStackTrace();
                    // Toast.makeText(UploadImageDemo.this,
                    // "MalformedURLException", Toast.LENGTH_SHORT).show();
                    Log.e("Upload file to server", "error: " + ex.getMessage(),
                            ex);
                } catch (Exception e) {
                    e.printStackTrace();
                    // Toast.makeText(UploadImageDemo.this, "Exception : " +
                    // e.getMessage(), Toast.LENGTH_SHORT).show();
                    Log.e("Upload file to server Exception",
                            "Exception : " + e.getMessage(), e);
                }

            }
        };
        thread.start();

        try {
            thread.join();      
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Debug.out("Message: " + serverResponseMessage.toString());
        return serverResponseCode;
    }
}

回答1:

As per your comment : "@Tarsem I want to show the progress dialog while uploading the image. So when the thread in ImageUploader is alive."

Try following apporach:

class imageupload extends AsyncTask<Void, Void, Void> {    
            Dialog dialog;    
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                dialog = ProgressDialog.show(context, "Uploading Image","Please Wait...");
            }    
            @Override
            protected Void doInBackground(Void... params) {
                // Upload Image HERE                    
                return null;
            }
            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                dialog.dismiss();                   
                // You can Call another AsynTask here (achieve sending email work here)             
             }
        }


回答2:

You can show a progress dialog in pre execute, do both uploading the image and sending the email in doInBackground and hide the progress dialog in postExectue.

Uploading the image in preexecute is contrary to what the async task is for... If you perform the uploading in doInBackground there is no need for an extra thread. (That's what the AsyncTask handles for you)

Or you could upload the picture and then (in postexecute) start another task for sending the email although I don't see why you need to do that asynchronous? You could also just send an intent to send the email...?



回答3:

Just use AsyncTask in following manner. In your main class make ProgressDialog's Object.

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

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        pd = new ProgressDialog(MainActivity.this);
        pd.show();
    }
         protected Integer doInBackground(URL... urls) {
            if(isPhotoTaken()){
            ImageUploader.uploadFile(getPhotoPath(), "http://www.example.com/upload.php",Step4.this);              
        }
        return null;
         }


         protected void onPostExecute(Integer result) {
           pd.dismiss();
         }
     }


回答4:

Async task comes with four methods onPreExecute() doInBackground() onPostExecute() and onUpdateProgress(), you just need to appropriately implement methods.

You show a progress in onPreExecute() do the upload and send email in doInBackground() update in onUpdateProgress() hide progress on onPostExecute().

EDIT

once you do it right you don't need thread anymore, because the main idea of AsyncTask is to make a separate thread/process and update the UI onPreExecute() onUpdateProgress() onPostExecute() runs on UI thread while doInBackground() fires a new thread, and can update UI by calling publishUpdate from within it, which in turn automatically call onUpdateProgress()