2012-09-10 82 views
2

我有一個應該在文件上傳過程中顯示進度的異步任務。除了它看起來完成文件上傳的速度真的非常快之外,一切都在工作,然後它就在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()調用時,它別無選擇,只能完成上載以獲取上傳狀態。有什麼方法可以讓它實際上傳,讓我可以得到合理的進展?

回答

0

您可以使用進度對話框類,如下所示,

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(); 
    } 
} 
2

這是郵政是如何設計的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應用程序。

0

您可以嘗試使用的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; 
     } 
    } 
} 
0

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

0

你可以這樣做:

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(); 
     }