在文件上传过程中显示进度条

问题描述:

我有一个应该在文件上传过程中显示进度的异步任务。除了它看起来完成文件上传的速度真的非常快之外,一切都在工作,然后它就在100%的等待中。在文件上传过程中显示进度条

我跟踪下来到

URL url = new URL(urlServer); 
connection = (HttpURLConnection) url.openConnection(); 

// Allow Inputs & Outputs 
connection.setDoInput(true); 
connection.setDoOutput(true); 
connection.setUseCaches(false); 

// Enable POST method 
connection.setRequestMethod("POST"); 

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

outputStream = new DataOutputStream(connection.getOutputStream()); 
outputStream.writeBytes(twoHyphens + boundary + lineEnd); 
outputStream.writeBytes("Content-Disposition: form-data; name=\"Filedata\";filename=\"" + pathToOurFile + "\"" + lineEnd); 
outputStream.writeBytes(lineEnd); 
long totalBytesWritten = 0; 
while (bytesRead > 0) { 
    outputStream.write(buffer, 0, bufferSize); 
    outputStream.flush(); 
    if (mCancel) { throw new CancelException(); } 

    totalBytesWritten += bufferSize; 
    if (mProgressDialog != null) { 
      mProgressDialog.setProgress(Integer.valueOf((int) (totalBytesWritten/1024L))); 
    } 

    bytesAvailable = fileInputStream.available(); 
    bufferSize = Math.min(bytesAvailable, maxBufferSize); 
    bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
} 
outputStream.writeBytes(lineEnd); 
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 

// Responses from the server (code and message) 
int serverResponseCode = connection.getResponseCode(); 

我注意到的是,有没有真正的延迟,直到在那里的得到响应代码的最后一行。我认为发生的事情是数据缓冲,看起来好像已经上传了数据,但并不是真的 - 它只是缓冲了数据。然后,当我到达getResponseCode()调用时,它别无选择,只能完成上载以获取上传状态。有什么方法可以让它实际上传,让我可以得到合理的进展?

您可以使用进度对话框类,如下所示,

ProgressDialog progDailog = ProgressDialog.show(this,"Uploading", "Uploading File....",true,true); 

new Thread (new Runnable() 
{ 
    public void run() 
    { 
     // your loading code goes here 
    } 
}).start(); 

Handler progressHandler = new Handler() 
{ 
    public void handleMessage(Message msg1) 
    { 
     progDailog.dismiss(); 
    } 
} 

这是邮政是如何设计的HTTP工作,所以不要指望它给你进步的详细信息。

您可以使用市场上的几种文件上传器组件之一。他们在内部使用flash或silverlight或iframe来显示进度。

http://dhtmlx.com/docs/products/dhtmlxVault/index.shtml

http://www.element-it.com/multiple-file-upload/flash-uploader.aspx

你会发现很多这样的人,如果你google了一下。

它们在内部使用原始IO代替http post来处理多个文件和进度通知。雅虎和谷歌也使用这些技术来制作邮件附件。

如果您真的很喜欢冒险,可以重新创建轮子 - 即编写您自己的组件。

编辑:

请注明,如果你想这样做在Windows桌面应用程序或Web应用程序。

您可以尝试使用的AsyncTask ...

创建onPreExecute方法的进度对话框,并驳回onPostExecute方法对话框..

请上传方法doInBackground()

例子:

public class ProgressTask extends AsyncTask<String, Void, Boolean> { 

    public ProgressTask(ListActivity activity) { 
     this.activity = activity; 
     dialog = new ProgressDialog(context); 
    } 

    /** progress dialog to show user that the backup is processing. */ 
    private ProgressDialog dialog; 

    protected void onPreExecute() { 
     this.dialog.setMessage("Progress start"); 
     this.dialog.show(); 
    } 

     @Override 
    protected void onPostExecute(final Boolean success) { 
     if (dialog.isShowing()) { 
      dialog.dismiss(); 
     }   
    } 

    protected Boolean doInBackground(final String... args) { 

//上传代码

  return true; 
     } 
    } 
} 

HttpURLConnection.setFixedLengthStreamingMode(...)做到了!

你可以这样做:

try { // open a URL connection to the Servlet 
      FileInputStream fileInputStream = new FileInputStream(
        sourceFile); 
      URL url = new URL("http://10.0.2.2:9090/plugins/myplugin/upload"); 
      conn = (HttpURLConnection) url.openConnection(); 
      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("uploadedfile", filename); 
      // conn.setFixedLengthStreamingMode(1024); 
      // conn.setChunkedStreamingMode(1); 
      dos = new DataOutputStream(conn.getOutputStream()); 
      dos.writeBytes(twoHyphens + boundary + lineEnd); 
      dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" 
        + filename + "\"" + lineEnd); 
      dos.writeBytes(lineEnd); 
      bytesAvailable = fileInputStream.available(); 
      bufferSize = (int) sourceFile.length()/200;//suppose you want to write file in 200 chunks 
      buffer = new byte[bufferSize]; 
      int sentBytes=0; 
      // read file and write it into form... 
      bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
      while (bytesRead > 0) { 
       dos.write(buffer, 0, bufferSize); 
       // Update progress dialog 
       sentBytes += bufferSize; 
       publishProgress((int)(sentBytes * 100/bytesAvailable)); 
       bytesAvailable = fileInputStream.available(); 
       bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
      } 
      // send multipart form data necesssary after file data... 
      dos.writeBytes(lineEnd); 
      dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 
      // Responses from the server (code and message) 
      serverResponseCode = conn.getResponseCode(); 
      String serverResponseMessage = conn.getResponseMessage(); 
      // close streams 
      fileInputStream.close(); 
      dos.flush(); 
      dos.close(); 
     } catch (MalformedURLException ex) { 
      ex.printStackTrace(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     }