上传图片时 ProgressDialog 不显示

Posted

技术标签:

【中文标题】上传图片时 ProgressDialog 不显示【英文标题】:ProgressDialog doesn't show when uploading Image 【发布时间】:2013-10-29 16:56:40 【问题描述】:

我有一个用于将图像上传到服务器的类。 上传时我想显示一个progressDialog来显示上传的进度。 然而不知何故,进度条没有出现。 这是我的 ImageUploader 类:

package com.OBO.Bandenanalyse;

//Imagine Imports here    

public class ImageUploader 
private Context context;
private ProgressDialog dialog;

public ImageUploader(Context ctx) 
    this.context = ctx;
    ((Activity) context).runOnUiThread(new Runnable() 
        @Override
        public void run() 
            dialog = new ProgressDialog(context);
            dialog.setCancelable(false);
            dialog.setMessage("Uploading Image... Please wait!");
            dialog.show();
        
    );


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

public int uploadFile(final String sourceFileUri, final String serverFile) 

    Debug.out("SourceFileUri: " + sourceFileUri);
    Debug.out("ServerFile: " + serverFile);
    Thread thread = new Thread() 
        @Override
        public void run() 
            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();
                dialog.dismiss();
            

            catch (MalformedURLException ex) 
                dialog.dismiss();
                ex.printStackTrace();
                // Toast.makeText(UploadImageDemo.this,
                // "MalformedURLException", Toast.LENGTH_SHORT).show();
                Log.e("Upload file to server", "error: " + ex.getMessage(),
                        ex);
             catch (Exception e) 
                dialog.dismiss();
                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();
        Debug.out("done uploading");
        dialog.dismiss();
     catch (InterruptedException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    

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

我在 AsyncTask 中调用该函数,因为我还需要做其他事情。我这样做是这样的:

private class MyAsyncTask extends AsyncTask<Mail, Integer, Double>
    /**
     * Private boolean to check if a tire is repairable or not.</br>
     */
    boolean _repairable = Step4._isRepairable;

    /**
     * Private integer which counts how many times we've tried to send the Email.
     */
    private int _counter = 0;

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute()
        super.onPreExecute();
        if(isPhotoTaken())
            ImageUploader uploader = new ImageUploader(_context);
            uploader.uploadFile(getPhotoPath(), "http://obo.nl/android-upload-image.php");              
        
    

    /**
     * Method used to start @link #postData(Mail) on a background thread.
     * 
     * @return null
     */
    @Override
    protected Double doInBackground(Mail... params) 
        postData(params[0]);
        return null;
    

    /**
     * Method used to send the mail through a JSON Request in combination with the website.
     * If there is no Internet connection the program will try to send the mail every 10 seconds.
     * 
     * @param valueIWantToSend
     */
    public void postData(Mail valueIWantToSend) 
        if(AppStatus.haveNetworkConnection(_context))
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://obo.nl/android-mailing.php");
            try 
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("from", valueIWantToSend.getFrom()));
                nameValuePairs.add(new BasicNameValuePair("to", valueIWantToSend.getTo()));
                nameValuePairs.add(new BasicNameValuePair("subject", valueIWantToSend.getSubject()));
                nameValuePairs.add(new BasicNameValuePair("message", valueIWantToSend.getBody()));
                nameValuePairs.add(new BasicNameValuePair("localized", getResources().getConfiguration().locale.getDisplayName()));
                if(PathToPDF(_repairable).contains("Goed_Gekeurd_NL"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_BANDENANALYSE_GOED_GEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Afgekeurd_NL"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_BANDENANALYSE_AFGEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Goed_Gekeurd_FR"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_ANALYSEPNEUS_GOED_GEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Afgekeurd_FR"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_ANALYSEPNEUS_AFGEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Goed_Gekeurd_DE"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_REIFENANALYSE_GOED_GEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Afgekeurd_DE"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_REIFENANALYSE_AFGEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Goed_Gekeurd_EN"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_TYREANALYSE_GOED_GEKEURD_PATH));
                 else if(PathToPDF(_repairable).contains("Afgekeurd_EN"))
                    nameValuePairs.add(new BasicNameValuePair("outputResult", SERVER_TYREANALYSE_AFGEKEURD_PATH));
                
                if(isPhotoTaken())

// ImageUploader uploader = new ImageUploader(_context); // uploader.uploadFile(getPhotoPath(), "http://obo.nl/android-upload-image.php"); nameValuePairs.add(new BasicNameValuePair("照片", getPhotoPath())); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); ResponseHandler responseHandler = new BasicResponseHandler(); 字符串响应 = httpclient.execute(httppost, responseHandler);

                //This is the response from a php application
                String reverseString = response;
                Log.i("info", reverseString);

                 catch (ClientProtocolException e) 

                 catch (IOException e) 

                
         else 
            if(_counter == 0)
                _counter++;
                _activity.runOnUiThread(new Runnable()
                    public void run()
                        Toast.makeText(_context, getString(R.string.noInternetEmailNotSend), Toast.LENGTH_LONG).show();
                    
                );

            
            try 
                Thread.sleep(10000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            postData(valueIWantToSend);
        
    


另外 _context 在活动的 onCreate 中是这样设置的:

_context = this;

在 PostData 方法中发生的事情是发送邮件,并将拍摄的照片作为附件(但这并不有趣,因为它工作得很好)。

那么为什么对话框没有出现呢?

【问题讨论】:

您可以在onPreExecute() 方法中创建对话框并在onPostExecute() 中关闭它,而不是在构造函数中创建对话框。 不,我不能,这太糟糕了。这是因为它仅用于上传图像。而 Asynctask 用于发送电子邮件。 (需要在附加之前上传图片)。 【参考方案1】:

首先,当您在 AsyncTask 的 onPreExecute() 中为 ImageUpLoader 创建对象时,您无需在构造函数中专门调用 runOnUIThread() 方法,因为 onPreExecute 在 UI 线程上运行并进行对话,试试这个... 删除 thread.join() 语句,

 Thread thread = new Thread()  
 public void run() 
      // your upload code stuff here
      activity.runOnUiThread(new Runnable()  
           public void run() 
             if(dialog.isShowing()) 
               dialog.dismiss();
             
           
      
 

当 UI 组件在 UI Thread 中创建时,它们很可能需要在 UI Thread 中处理。 (试图关闭新线程中的对话框)

【讨论】:

Hmmm 这行不通,因为tread.join用于检查线程是否完成了图像的上传。【参考方案2】:

您没有在 ImageUploader 方法中启动线程。将您的方法更改为:

public ImageUploader(Context ctx) 
this.context = ctx;
((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();
    
).start();

【讨论】:

嗯,如果我添加 .start();它不会再编译了:Cannot invoke Start() on primitive type void。 .start() 是必要的,因为您的线程永远不会启动。可能是因为您没有设置 ProgressDialog 样式。我已经编辑了我的答案再次测试它。 即使添加了样式,它仍然不起作用。然而我确信我应该开始这个话题 你为什么使用 rubOnUiThread?正常线程有什么问题?因为我使用普通线程来等待用户对话框并且工作得很好。 那是因为它是一个 UI 元素,所以从技术上讲它应该在 UI 线程上运行,但让我尝试将它放在普通线程上。

以上是关于上传图片时 ProgressDialog 不显示的主要内容,如果未能解决你的问题,请参考以下文章

自定义ProgressDialog加载图片

自己定义ProgressDialog载入图片

Xamarin.Android:ProgressDialog 不显示

Android:ProgressDialog 不显示

ProgressDialog 不显示 [重复]

为啥上传的附件图片不显示?只显示个链接